I have these classes:
public class NegativeNumberException extends Exception{
NegativeNumberException()
{
System.out.println("Don't pass negative values!");
}
public String getMessage()
{
String message="NegativeNumberException";
return message;
}
}
public class Main {
static void test(int n) throws NegativeNumberException
{
if(n<0) throw new NegativeNumberException();
else System.out.println("Success");
}
public static void main(String[] args) {
try
{
test(-5);
}
catch(NegativeNumberException nne)
{
System.out.println(nne);
}
}
}
This is the result:
Dont pass negative values!
NegativeNumberException: NegativeNumberException
I expected it to print NegativeNumberException once, i guess if i override getMessage it gets executed no matter what, is it correct or something else is going on?
All objects have a toString() implementation. Because java.lang.Object itself (and Exception extends Throwable, and Throwable extends Object - all things eventually extend object) has this.
The Throwable class overrides the implementation of it with:
#Override public String toString() {
String s = getClass().getName();
String message = getLocalizedMessage();
return (message != null) ? (s + ": " + message) : s;
}
and getLocalizedMessage() is implemented as:
public String getLocalizedMessage() {
return getMessage();
}
whenever you 'append' an object to a string (with X + Y, where the X expression has type String and Y is anything) is shorthand for X.concat(Y.toString()). Thus, you're calling toString there. You did not override it, so you get Throwable's implementation of it, which invokes getLocalizedMessage - which you also didn't override, so that calls getMessage(), hence, you get your text. Twice.
Some lessons:
Do not System.out anything in exception constructors. The exception goes someplace and if it needs printing, where-ever it ends up will print it. If an exception ends up 'ending' your static void main(String[]) method, java will print it for you.
The message should not end in punctuation (and definitely not an exclamation mark - it's an exception. That something went wrong is assumed, no need to yell about it), and should not repeat or consist of the exception type. That information is already available; the message exists for additional information. If you have nothing to add, then don't have a message. An exception named NegativeNumberException should probably have the actual number as message, or possibly the param name. Something like:
public class NegativeNumberException extends Exception {
public NegativeNumberException(String msg) {
super(msg);
}
}
and then in your test method:
if (n < 0) throw new NegativeNumberException("n: " + n);
Overriding getMessage and returning some string constant is almost never correct. Messages should rarely be constants, as they are meant for detailing the specifics of the problem, not for generally explaining what the exception represents (write some javadoc for that, and only if the name of the exception is not sufficient to figure it out, hence, nothing needed here).
Related
How I can scan my code and get all possible throws MyException errorCode's of execute() function?
Errors const:
public enum ErrorId {
OK(1),
REPORT_LIMIT(2),
NOT_UNIQUE_FIELD(3),
INCORRECT_PROPERTY(4);
private int id;
ErrorId(int id) {
this.id = id;
}
}
For example I have 'MyException' :
public class MyException extends Exception {
#Getter
protected final ErrorId errorCode;
public MyException(ErrorId errorCode) {
this.errorCode = errorCode;
}
}
And class with method:
public class MyClass {
public void execute() throws MyException {
//do something 1
...
if(isSomethingWrong1) throw new MyException(ErrorId.REPORT_LIMIT);
executeMethod2();
//do something N
if(isSomethingWrongN) throw new MyException(ErrorId....);
}
public void executeMethod2() throws MyException {
// ...
throw new MyException(ErrorId....)
// ...
}
}
I don't think there's an answer here that you'll like.
Reflection won't work in this case, because it's concerned with types, not values. The compiler can't help you here, either, because if the error code comes in through a variable, then at runtime, all bets are off -- the value could be any possible value of the type you're using. If you're using an enum for the code value, then you have a known list of all possible values, but you won't know which ones are actually used in any particular function without reading that function. A static analysis tool may be of use here, but you'd need to continue running it over time to keep this information up to date.
However, all is not lost. As I said in my second comment, you have another choice -- extract subclasses. Let's consider this definition of your Exception class.
public abstract class MyException extends Exception {
#Getter
protected final ErrorId errorCode;
public MyException(ErrorId errorCode) {
this.errorCode = errorCode;
}
}
It's the same as yours is now, but it's abstract. This class is open for extension. So we could create a subclass ReportLimitException like this:
public class ReportLimitException extends MyException {
public ReportLimitException() {
super(ErrorId.REPORT_LIMIT);
}
}
and another like this, for example:
public class DuplicateFieldException extends MyException {
public DuplicateFieldException() {
super(ErrorId.NOT_UNIQUE_FIELD);
}
}
Now, any given method can advertise which particular exceptions it uses via its throws clause. This is, in fact, why that clause exists.
public void execute() throws ReportLimitException, DuplicateFieldException {
//do something 1
//...
if(isSomethingWrong1) throw new ReportLimitException();
executeMethod2();
//do something N
if(isSomethingWrongN) throw new DuplicateFieldException();
}
At this point, if you advertise the exceptions explicitly, you'll have achieved your goal, at the cost of some potentially long throws clauses (which should actually be a hint to you that the method may be doing too much work anyway). Alternatively if you don't want to advertise every exception like that, you could also use your IDE's "find references" feature to locate every place where those exceptions are created (look for references to the constructors).
And the calling code doesn't even have to be aware of the change. It can continue using code like this:
try {
// stuff that might throw any of your exceptions
} catch (MyException ex) {
switch (ex.getErrorCode()) {
// handle the cases...
}
}
Is it possible to throw an exception whenever a mock is called with non-predefined arguments? There is Answers.RETURNS_SMART_NULLS, but it's not really what I need, since it doesn't work if null is legitimate return value, which doesn't lead to NullPointerException, but rather to errors later on.
Edit: some background. So, in Mockito when you define a mock, you specify the return values for each call like this:
when(myMock.someMethod(arg1, arg2)).thenReturn(returnValue);
When myMock.someMethod is called with arguments, for which I didn't give a return value in the test, it just returns null. I would like to configure it to crash right away and tell me that I forgot to define the return value for some combination of parameters.
Edit 2: There were suggestions to provide a custom defaultAnswer that would throw exceptions when called. Unfortunately, this doesn't work. The default answers' answer() method is called even if a mock is present. Here's a sample:
public class Test {
public static class Adder {
public int add(int a, int b) {
return a + b;
}
}
public static final Answer<Object> THROW_ON_UNDEFINED_ARGS = new Answer<Object>() {
#Override
public Object answer(InvocationOnMock invocation) throws Throwable {
throw new IllegalArgumentException(
String.format("Calling a mock with undefined arguments: %s %s",
invocation.getMethod(),
Arrays.toString(invocation.getArguments())));
}
};
public static void main(String[] args) {
Adder adderMock = mock(Adder.class, THROW_ON_UNDEFINED_ARGS);
when(adderMock.add(2, 3)).thenReturn(5);
System.out.println(adderMock.add(2, 3));
}
}
The exception is thrown even though adderMock.add(2, 3) is defined.
You could provide a default Answer in the construction of your mock that always throws an exception. Then every call that is stubbed will act like usual. Everything outside those paths will throw an exception. Something like this:
final String arg = "some arg";
Collection<Object> object = mock(Collection.class, new Answer<Object>() {
#Override
public Object answer(InvocationOnMock invocation) throws Throwable {
throw new IllegalArgumentException("You cannot invoke " + invocation.getMethod() +
" with " + Arrays.toString(invocation.getArguments()));
}
});
doReturn(true).when(object).add(arg);
object.add(arg); // Goes ok
object.add("azertyuiop"); // Throws the exception
Just point another way you can do that, using thenAnswer:
when(myMock.someMethod(anyString(), anyString())).
thenAnswer(new Answer<String>() {
#Override
public String answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
String arg1 = (String) args[0];
String arg2 = (String) args[1];
if ("arg1".equals(arg1) && "arg2".equals(arg2)) return "someValue";
throw new Exception();
}
});
myMock.someMethod("arg1", "arg2"); // Returns "someValue"
myMock.someMethod("xxx", "yyy"); // Throws Exception
Hope it helps.
First, a bit of "good engineering" mumble - why would you like to do this? Mockito tries to 'promote' BDD style - you set up (mock) your calls, you execute the code and verify interactions were exactly as you expected rather then 'it didn't called anything else' - Do you try to do something described in Finding irrelevant invocation?
Generally if I want to mock all the cases, but one - this makes my ask myself whether my tests are really OK.
Anyway, to the topic :)
In Mockito, you can define multiple whens with different values, like
class Foo {
public String bar(int a) {
return "bar = " + a;
}
}
Mockito.when(task.bar(Matchers.anyInt())).thenReturn("L")
Mockito.when(task.bar(3)).thenThrow(new IllegalAccessError())
task.bar(4); // returns "L"
task.bar(3); //throws IllegalAccessError
Notice that the order of whens DOES matter. The rules are processed in reversed order (or rather overrides the actual matchers).
In my code we first mock for anyInt, then for 3 - which works. If you reverse it - both calls to bar() will return 'L'.
I am learning features in java including exceptions. I am writing a custom exceptions. Here is what i am doing :custom exception class:
public class ServiceException extends Exception {
private String customMessage;
public ServiceException(String customMessage) {
super(customMessage);
this.customMessage = customMessage;
}
}
Main class:
public class Main {
public static void main(String[] args) {
try {
new Main().test();
} catch (Exception e) {
System.out.println("the exception message is " + e.getMessage());
}
}
public void test() throws ServiceException {
try {
int i = 1 / 0;
} catch (Exception e) {
throw new ServiceException(e.getMessage());
}
}
}
This much i know:
if super class constructor is not invoked in the custom exception class, the message set in the custom exception is not passed to the Exception class. But if i have a method public String getMessage in my custom exception class, even if the super is not invoked, that message is printed . Sorry if this is a naive question. But i am failing to understand he concept. Could come one help clear the concept ?
In main where you are catching the error, you are basically assigning a ServiceException object to a Exception reference, i.e. assigning derived class object to base class reference, so if the derived class has overridden the method, it will get called.
the e.message() being called is from ServiceException not Exception, you are right, no data is being passed when you are not calling super, data is inside ServiceException class only and the function invoked is also from ServiceException class.
That is because you are supplying it. You are passing e.getMessage() to your constructor as the only argument, customMessage. You then pass customMessage to its parent's constructor that takes a String, Exception(String). In doing so, you are giving it the message to use for serviceExceptionInstance.getMessage(). Instead, do not pass the customMessage to its parent (use super();, which is implied if no call to a parent constructor is given and a no-arg, parent constructor exists). Then the message will be null as it is not supplied.
In other words:
new ServiceException(e.getMessage());
Creates a new ServiceException with the message from e. You pass that message to Exception, ServiceException's parent.
super(customMessage);
In doing so, you use the single argument, String-based constructor of Exception. Passing a value to that constructor implies that you want it used when callers invoke getMessage. To avoid doing this, call a different parent constructor, or none at all (calling none is technically not possible, and it will implicitly do super(); for you):
public ServiceException(String customMessage)
{
this.customMessage = customMessage;
}
This will call super(); for you, which means that the parent class has no message to send, and by not overriding getMessage() yourself, then it will return its default value (null). To be clear, Exception itself extends from Throwable, which is really the class providing this functionality, but it all stems from how you work with Exception as it serves as a pass-thru to Throwable.
I'm looking to clean up the exception mess that is currently the code base I'm working on.
The basic setup is this.
I have an interface that is implemented by a lot of classes that looks like this:
public interface TerminalMessage<E> {
// Override for specific return data type.
public E send(TerminalStream stream) throws Exception;
}
These classes throw a lot of different exceptions, like IOException, InterruptedException etc.
As it is now, all I do is call getMessage() on the catched exceptions and relay this message to the ui-code.
This is not very nice since I sometimes get bogus messages displayed to the user and I catch unwanted exceptions.
I'm thinking of creating a custom exception class (TerminalException) that would wrap all these kinds of exceptions.
However I'm not sure where to do the wrapping, should the wrapping be done where the exception is first thrown (in the output stream for example) or in every send() method. The former has the advantage of not adding much code, but it makes more sense to me that a stream throws IOException rather than a TerminalException.
The above design also doesn't really solve the sometimes bad messages displayed to the user, so some tip on how to transform the thrown exceptions into something useful to the user would be great!
Thanks!
a custom exception is a very good idea if you have useful information in it like an error code.
just wrap everything with your TerminalException, but do not forget the cause
OR
use the first TerminalException thrown:
public class MyException extends Exception{
String errorMessage;
public MyException(String message, Exception cause){
super();
if(cause instanceof MyException){
// already wrapped
errorMessage= cause.getErrorMessage();
initCause(cause.getCause());
}
else{
// not my Exception
errorMessage=message;
initCause(cause);
}
ยด
}
}
Another option could be to use a Template Method Design Pattern and "control" the exeptions therein as follows:
public abstract TerminalMessage<E> {
public abstract E doSend(TerminalStream stream);
public E send(TerminalStream stream) throws Exception {
// do common stuff here
try {
doSend(stream);
}
// catch more specific exceptions first
// handle all the exceptions accordingly here, thus controlling
// in one central location what will be thrown externally
catch(Exception) {
}
}
}
This way the exception handling for all of the derived classes will be the same and and localized, and the derived classes wont have to do anything special.
From many designs I have tried, this is the final one which I happily use on some projects.
public enum ExceptionCodes {
IOException("ioexception", false),
UserNotFound("usernotfond", true);
private static final String BUNDLE_NAME = "SOME_bundle_name";
private final String bundleCode;
private final String isManagable;
ExceptionCodes(String bundleCode, String isManagable) {
this. ...
...
}
public String message() {
// eventually get locale from somewhere, for example some threadLocal
return SomeBundleResolver.resolve(BUMDLE_NAME, bundleCode);
}
public Boolean isManagable() {
return isManagable;
}
}
public class MyGenericException extends RuntimeException {
private final ExceptionCodes exceptionCode;
private final Throwable throwable;
public MyException(ExceptionCodes exceptionCode) {
this....
...
}
public MyException(ExceptionCodes exceptionCode, Throwable throwable) {
this. ...
....
}
public Boolean isManagable() {
return exceptionCode.isManagable();
}
public String getMessage() {
return (throwable == null) ? super.getMessage() : throwable.getMessage();
}
...
}
Point is that exception codes are managed at one place. You can add custom atributes to enum like error codes etc. One of the many problem with exceptions is that if you do not know how to handle exception at place it is unprobable you will know how to handle exception layer above. Then just two cases can occur. Either exception can be displayed in some format to user, or system has to crash in some gracefull way. Attribute isManagable is exactly about this. If exception si not managable system must go down. So the exception is handled just at top level of application in general error handler. This way you can prevent Exception explosion.
import java.io.*;
class MyException1
{
static String str="";
public static void main(String args[])
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter your food");
try{
str=br.readLine();
}catch(IOException e){
System.out.println("Exception has been occurred"+e);
}
try{
checkFood();
}catch(BadException be){
System.out.println("Exception"+be);
}
}
private static void checkFood() throws BadException
{
if(str.equals("Rotten")|| str.equals("")){
System.out.println("Bad food");
//throw new BadException();
throw new BadException("Not Eatable");
}else{
System.out.println("Good food !! enjoy");
}
}
}
class BadException extends Exception
{
String food;
BadException()
{
super();
food="invalid";
System.out.println(food);
}
BadException(String s)
{
super(s);
food=s;
}
public String getError()
{
return food;
}
}
In the program, how is it that this public String getError() returns the food variable? I have not called it anywhere?
If I remove the line super(s);, then "Not Eatable" does not get printed. But if I leave that line in, then it does get printed out. How does this program flow work?
If I remove the line super(s);, then "Not Eatable" does not get printed. But if I leave that line in, then it does get printed out. How does this program flow work?
super(s) will call the "super class" constructor that takes a string. Just like if you had called new Exception("Not Eatable"). This constructor for Exception adds a message to the exception, so when you print it out, it will contain that text.
This has nothing to do with the variable food. You could remove the line food=s;, and the message would still print out correctly.
See this tutorial on the keyword super:
http://download.oracle.com/javase/tutorial/java/IandI/super.html
If you're still confused about how super works, then think about this. You can recode BadException with this code, and your program will still do exactly the same thing:
class BadException extends Exception
{
BadException(String s)
{
super(s);
}
}
This will also do the same thing:
class Test extends Throwable
{
String message;
Test(String msg)
{
message = msg;
}
public String toString() {
return "BadException: " + message;
}
}
class BadException extends Test
{
BadException(String s)
{
super(s);
}
}
When you throw new BadException("not eatable"); you're instantiating a new BadException, which sets its member variable food to the string "not eatable". Then the call to getError() will return that string.
It would be better style to to get rid of the food member variable and just make a call to super(String) since there is a constructor Exception(String message)
"super(s);" calls the super-class's constructor that takes one String. That is the Exception class.
If you take out "super(s);", then the compiler will implicitly put a "super();" call in there, because the super class has a default constructor. (That's why it's called a default constructor -- because it will get called by default if you don't specify anything else!)
Since that's the same as calling "super(null);", the message (which is in the variable "s") doesn't get passed up to the super class, and thus it isn't there to print out ..