It is possible in Java to throw any Exception even if it is just declared on moment of throwing, example below:
import org.springframework.dao.DataAccessException;
// DataAccessException - is abstract class
} catch (DataAccessException dae) {
throw new DataAccessException("Exception while executing SQL: \n" + sql
+ "\nparams: " + paramsToString(params), dae) {
private static final long serialVersionUID = 1L;
};
}
Please share your ideas how bad or good this approach.
the same question to extending RuntimeException (that is not abstract) and throw it right away.
Please share your ideas how bad or good this approach.
It should be legal ... according to my understanding of the Java language.
I think it is pointless from a functional perspective. The caller still has to catch the base exception that you created the anonymous subtype of. And it is not like the name of an anonymous subclass conveys any useful information ...
I think it is bad from the perspective of code readability and maintainability. It is obscure for no good reason, and no useful effect that I can discern.
And there is a risk that doing something weird like that it might break things .... such as your debuggers, source-code analysers or some other tool in your Java chain.
In summary, it is a bad idea with no redeeming features.
Yes. Your example is perfectly okay. An Exception instance is just a class (that extends Exception) name plus information that will be needed when it's caught. Often the class name is all you need (for the catch statement). Normally a message and a stack trace are included. (Though they're both rather useless for caught exceptions.) But sometimes more info is needed. Extending a class is one good way to do that.
If performance matters (which when working with SQL it might not) override fillInStackTrace. Filling in the stack trace is slow, and if you're planning to catch the exception, you don't need it.
Don't extend RunTimeException; you won't be warned about methods that could throw it and you may forget to catch it.
Related
I've been trying to write some logic regarding exception handling from Evernote Java API.
I stumbled upon a weird situation.
There are two exceptions - EDAMSystemException and EDAMUserException
(documentation link)
Both of those exceptions have a method EDAMErrorCode getErrorCode() however they lack a common interface for this method.
I really feels like its just a flaw in their API design, since they state that some of those codes only make sense for EDAMSystemException and others for EDAMUserExceptions
Since they do not clearly state which EDAMErrorCode bounds to which exception, and shielding myself from situation that some of those codes are use in both of the exception types I wanted to write a try-catch block:
try {
clientFactory.createNoteStoreClient();
} catch (EDAMSystemException | EDAMUserException ex) {
switch (ex.getErrorCode()) {
case INVALID_AUTH:
case BAD_DATA_FORMAT:
..
case AUTH_EXPIRED:
...
case RATE_LIMIT_REACHED:
...
default:
...
}
} catch (TException ex) {
...
}
but (obviously) I cannot call ex.getErrorCode(). I could do instance checking (instanceof + cast), but it seems not elegant.
I was trying to think about some generic solution to this problem, but lack of common ancestor prevents me from using bounded generic.
Creating a wrapper class with two constructors and getMessage() method still forces me to do instance checking.
Am I missing something or is there really no way around it and I have to do the checking anyway?
When I throw checked exceptions from a method should I just declare the super class of the exceptions in the method signature or all the different types? If I have the following exceptions:
private class SuperException extends Exception {
}
private class SubExceptionOne extends SuperException {
}
private class SubExceptionTwo extends SuperException {
}
Should the method signature be:
void confirmAccount() throws SubExceptionOne, SubExceptionTwo;
or
void confirmAccount() throws SuperException;
In the last method signature, how do I tell other developers what exceptions that could be thrown from the method? If the different sub types need different handling?
The interface should be as stable as possible. So probably Super. Many libraries use the "Super" strategy, because exception specs cause far more annoyance in maintainability than readability or safety they add. Even the IOException is a Super that nearly all Java library code uses instead of declaring more specific exceptions. (But when they do declare more specific exceptions, it's because the contract is that more general IOExceptions won't be thrown. Read on.)
You might list Sub1 and Sub2 if you really do want to say each of those exceptions can be thrown, but don't want to say that any derivative of Super can be thrown. Perhaps Sub1 is NumberCrunchException and your method calls crunchNumbers() and users of your method can be assured that's the only exception-ful thing your method does. In that case the specific strategy is better.
If the different sub types need different handling, then definitely declare the two different exceptions. Never expect the developer using your method to guess that you are actually throwing different types of exceptions.
If you declare two distinct exceptions, and the user knows from the Javadoc that they are actually descendents of the same class, the user may choose to catch them both with a catch (SuperException e) rather than two individual catch clauses. But it depends on the user's choice.
If you don't declare them separately, your IDE is not going to add the appropriate #Throws to your Javadoc comment. And your Javadoc will therefore only indicate that you're throwing SuperException, which will leave the user in the dark. Solving this by just putting it in the text of the comment is not a real solution. If any tool is using reflection to determine what your method throws, it will not see the individual exceptions in the array returned from Method.getExceptionTypes().
If the functionality expected of the different exceptions is more or less the same and it's just a matter of how they will appear in the logs, it may be better to just use the parent exception, with different messages.
The throws clause is there to convey useful information to the calling method about what might go wrong during invocation of this method. That means that how specific you are will depend on how much information you want to convey; and that will be application-dependent.
For instance, declaring throws Exception is almost always a bad idea: the information this conveys is just "something might go wrong", which is too vague to be useful. But whether calling classes are going to need perfectly fine-grained information in the throws clause is something you need to decide by looking at your program. There's no set answer.
Java Runtime Exception is used to check un-checked exception. It is accepted standard that to sub class JavaRunTimeException. Can you please explain me the reason behind sub classing without directly using it as below.
try {
int x = Integer.parseInt(args[0])/Integer.parseInt(args[0]);
} catch (RuntimeException e) {
}
Recommended approach
public class ServiceFaultException extends RuntimeException {}
try {
int x = Integer.parseInt(args[0])/Integer.parseInt(args[0]);
} catch (ServiceFaultException e) {
}
I would like to know reasons for this recommendation. ?
Exceptions are used to give some meaning to an error that is not handled right away where it occurs.
Subclassing RuntimeException allows you to give more meaning and differentiate between several RuntimeExceptions.
For instance, it is useful to be able to tell the difference between IllegalArgumentException and NumberFormatException, which are both RuntimeExceptions.
EDIT: As #Dyrborg said, catching RuntimeException can also be dangerous because anything could throw it without your knowledge. Better handle only what you control.
ASIDE:
You could tell me "why not a checked Exception then ?".
I usually use RuntimeExceptions when it corresponds to an incorrect use of a method (illegal argument for instance). It means something the programmer can ensure to avoid. When it comes to user input, or internet connection, which is not reliable, then Exceptions are more appropriate, because the programmer must handle these error cases.
Can you please explain me the reason behind sub classing without directly using it as below.
The same reason as applies to subclassing any other exception. The language provides the facility to catch specific subclasses, so why wouldn't you use it?
The type of an exception is often enough to handle it properly (for example you try to open a file and get a FileNotFoundException). However there are cases where you might catch multiple exception of the same type. For example, an IllegalArgumentException that can be caused by more than one argument. The IllegalArgumentException does not add any additional methods (or public fields) to the Throwable interface (accoding to the online javadoc) which means that the only information that you can rely on are the nested exception (which may or may not exist) and the message (which is for human consumption).
I don't like the idea of extending IllegalArgumentException to add structured information to it, because other people would have to learn the new class. And I don't like the idea of littering projects with very specific exception classes.
Using the message field is also a bad idea because it's not meant for programmatic access.
I think IllegalArgumentException should have included details such as the class function and argument(s) in question. And in general custom exceptions should provide additional detail (other then just their type) for a more fine grained exception handling.
What are considered generally the best practices for designing exception classes, and handling exceptions of the same type?
As a general rule, I think it is ideal to have one class of exception per "type of action a caller might reasonably want to take". Of course, for one's own custom exceptions there could be a boolean or enum field providing some extra disambiguation, rather than creating trivial subclasses.
In your specific case I'm not convinced that trying to handle the exception is a good idea. RuntimeException and its subclasses usually represent coding issues, and the same is true of IllegalArgumentException. If the argument is illegal it shouldn't be passed in in the first place.
If you're in a situation where you're not sure if an argument is valid (maybe it's user input, or maybe you don't know the specific object you're calling the method on) then a better approach would be to have some way of checking the validity of the argument before passing it. Rather than say "do this" and catch the exception, ask "can I do this?" before calling.
Exception classes should be designed so as to provide all that is needed when they are caught. Note that try/catch statements are actually a form of type switch, so in general it is cleaner to create additional exception classes rather than confuse program logic by nesting too many if's within catch clauses.
It has to be said that catch clauses are not very convenient if you want to organize your error handling code in an object oriented fashion, so there are different trade offs to keep in mind.
Note that standard exception classes do have information available on what piece of code caused the exception, even though I would not advise you to base on it your error handling logic.
If the current exception was thrown in a catch clause for a different exception this should be available with the getCause() method, while the getStackTrace() should provide access to the stack of calls that were active when your exception was thrown.
Again I don't advise you to use this information except for debugging purposes.
Its true that the predefined exception classes are very general. But if you want more specific details about the exceptions then you should go for user defined exceptions. you should create your own exception classes with any level of details!
here is the pseudo code:
public class TooManyArguments extends exception{
public String toString(){
return ("..whatever information you want to give for this exception..")'
}
}
and whenever you encounter exceptional situation throw an instance of this class
throw new TooManyArguments();
I am recently thinking about if throwing constructor from Java is good or not. Currently this is what I gathered:
Can constructors throw exceptions in Java?
Here, Mr. StackOverflow (aka Jon Skeet) does not seem to hold anything against it, but he did hint about having subclass throwing exceptions. What will happen (anything bad?) when subclass throws exceptions?
http://futuretask.blogspot.com/2006/05/java-tip-10-constructor-exceptions-are.html
This blog post "Constructor Exceptions are Evil" tells me a way to show that constructor exceptions could be dangerous. However, the example seem to be really esoteric. Is there any real danger here?
I am thinking that if static factory methods (Effective Java 2nd ed., Item 1) are used instead of public constructors, we could safely remove the exceptions from constructors to the static factory method. Is this a valid way to avoid constructor exceptions and is this useful or used in anywhere?
Any inputs are helpful & appreciated. Thanks!
There is nothing wrong with exceptions in constructors (or factory methods, either way is fine). sometimes, doing too much work in a constructor can be a poor design, and may make sense to move to a factory method.
the only thing that point 2 proves is that exceptions in constructors are not an adequate security mechanism for protecting a class from evil usage. however, there are any number of ways to subvert such a design, which is why the only way to truly run secure code in java is running with a SecurityManager. so point 2 is just a straw man argument.
My point about a subclass throwing an exception is a situation like this:
public class Parent {
private final InputStream stream;
public Parent() {
stream = new FileInputStream(...);
}
public void close() throws IOException {
stream.close();
}
}
public class Child extends Parent {
public Child() {
// Implicit call to super()
if (someCondition) {
throw new RuntimeException();
}
}
}
Now the Child class really should call close() if it's going to throw an exception. Of course, if close() is overridden by yet another layer of inheritance, that could also cause problems. Just another example of how inheritance gets messy.
I still think it's basically fine for constructors to throw exceptions. Even your second link was more about an evil way of capturing the not-successfully-constructed object rather than really about constructor exceptions being evil - it certainly doesn't give any reasons for not throwing exceptions from constructors. It doesn't even give the messy situation I mentioned.
Factory methods could potentially help, but as far as the caller is concerned the result is the same: they don't get to see the partially-constructed object. Unless you really need to do something like clean-up on an object which was constructed but then failed some element of validation, I don't think that should be a reason to use factory methods instead of constructors. (There are other reasons to do so, but that's a different matter.)
I believe throwing exceptions from constructors is fine, more so the one's which checks for the preconditions to a successful object creation, example IllegalArgumentException.
However, I do not believe that constructors are the right place to handle business logic or throw business exception/ custom exceptions.
As for the reasons cited to not throw an exception, IMHO they are quite contrived; bottom line is if a careless developer wishes to do something evil he can find numerous ways to do it and there's no stopping till the developer does a self review of the code/ follows best practices.