Let say I have 2 projects A (API), and B (implementation).
My sonar-lint tells me I should never throw Exception because it is too generic. So, what should be the proper way to handle any kinds of exceptions in the API, including both runtime and "checked" exceptions ?
Project A
public interface IBuilder {
public void create() throws Exception;
}
Project B
public abstract class ABuilder implements IBuilder {
public void create() throws Exception {
throw myImplException();
}
}
public class ARealBuilder extends ABuilder {
public void create() throws Exception {
//Some Exceptions and RunTimeExceptions can occurs
}
}
If I create my own exception type like this:
public class myException extends Exception {
}
Does this handle RuntimeExceptions ?
Just my two cents, but as I started typing it in a comment it became too long:
Throwing Exception doesn't provide any useful information, what do you do in the catch part of your API method? You always have to handle all exceptions and/or re-throw them.
The proper way of handling exceptions has to be done in the implementation part (Project B):
Is the information not useful or can/should be handled Project B? Handle it (via a retry mechanism or providing a meaningful default value, e.g. user not found in session => return an UnknownUser object or null).
Is the information useful for Project A? Define a project specific exception, e.g. UserNotFoundException and throw that one. Then Project A can handle that specific case.
You don't need to define the RuntimeExceptions as they are bubbling up the call stack until Project A anyway (if not handled/catched before in Project B), but yes they are also children of Exception.
Related
I want to create user-defined exception with addition but I get a compilation error.
class Test{
public static void main(String[] args){
int a=9, b=67, result;
result = a+b;
throw new Add("Addition has been performed");
}
}
class Add extends Throwable{
Add(){
printStackTrace();
}
Add(String message){
System.out.println(message);
printStackTrace();
}
}
The error is:
Practice.java:8: error: unreported exception Add; must be caught or declared to be thrown
throw new Add("Addition has been performed");
I would point out that irrespective of the compilation error, and the possible fixes, it is a bad idea to extend Throwable.
It is unnecessary. You can / should extend Exception or RuntimeException or any of their subclasses.
There is a lot of code that assumes that all exceptions are Exception or Error or their subtypes, not some "random" subtype of Throwable.
The generic meaning of a random subclass of Throwable is unclear; e.g. see Which subclass of Throwable should be caught and which shouldn't?
See also the discussion in this Q&A:
Extending Throwable in Java
It is also a bad idea for an exception's constructors to be printing or logging error messages and stacktraces. It should be up to the code that catches the exception to decide what to do with them.
To make your exception unchecked declare it in the following way
class Add extends RuntimeException {
}
Either catch/rethrow the Add throwable
or extend it from RuntimeException - they are not mandatory to be caught.
class Add extends RuntimeException
If you do not want to make your exception unchecked you need either to declare that your method might throw this exception
public static void main(String[] args) throws Add {
or surround it with try/catch statements
try {
throw new Add("Addition has been performed");
} catch (Add add) {
add.printStackTrace();
}
Overall I would suggest you to use an IDE they are really good at helping you with these kind of problems.
You have Successfully created and throw the Exception but use Try and
Catch block to handle it.
First, in Java there are 2 types of exception. Checked and unchecked. Checked are exceptions thrown that you have to handle by either catching them ( surrounding the block, portion of code, containing methods that would throw an exception like yours) or declaring that the parent method calling this method throwing an exception.
Throwable is base class of all errors in Java. There are multiple types of errors, a sub type Is exceptions.
Important to not as well is that you seem to throw an exception on success which isn’t the best to do because exceptions are costly in terms of resources. Better use events in this case to broadcast that addition happened.
Consider this:
public void Do() throws Exception {
if (blah) throw new Exception(...);
Thingy thingy = ...;
Foo(thingy);
}
public void Foo(Thingy thingy) throws EmptyThingyException {
if (thingy == null ||
thingy.isEmpty()) throw new EmptyThingyException();
...
}
public class EmptyThingyException extends Throwable { ... }
In this case, is it okay to not handle EmptyThingyException inside Do and declare Do like so:
public void Do() throws Exception, EmptyThingyException {
or do I have to handle EmptyThingyException inside Do and throw it back again like so:
public void Do() throws Exception, EmptyThingyException {
try {
} catch (EmptyThingyException empty) {
throw empty;
}
...
}
The short answer to the question is:
Yes, it's correct to declare a checked exception thrown by a called method.
How a method achieves its purpose is an implementation detail and it shouldn't matter to the interface how much it does directly or how much it delegates to methods. The language rules about checked exceptions are carefully defined to make sure methods advertise all checked exceptions they may throw or methods they call throw (but are not handled by the method itself). Letting an unhandled exception get 'thrown through' a method is how things are supposed to work.
Indeed the answer is in the name of the construct "non-local exception handling" it was conceived to take effort out of endless error handling all the way up a call chain when the only real action is "that didn't work" at some point near the start.
To align to that method, you should only catch exceptions you're going to do something about.
Clean up code should be achieved with finally so the normal reasons to catch an exception are to log it and/or abandon a task at some point rather than letting the stack unwind further.
In this specific case the best answer would be to throw an IllegalArgumentException:
throw new IllegalArgumentException("thingy==null || thingy.isEmpty()");
That's unchecked and wisely so. Correct code shouldn't encounter illegal arguments and they should expect to be thrown rarely and be indicative of program flaw (either in the class, it's package or consumer code). External and user input should be validated directly and programs shouldn't rely on IllegalArgumentException.
In practice IllegalArgumentException and IllegalStateException should cover 'internal errors' meaning "You can't do this with that" or "You can't do that right now" respectively and should be commented to specify the fault.
The idea that you might sub-class those two because consumer code might respond differently to different illegal actions it might take is bodging pure and simple.
Program correctness includes that a program never makes an illegal call on some other part of the program or enters an invalid or corrupted state and exceptions only occur as a result of environmental failures that mean a program or sub-task in a program cannot be completed as intended.
if you want to do something after exception happen, then use try-catch, or you can just declare it on the method.
Beyond that, if EmptyThingyException is sub class of Exception, then it is no need to declare EmptyThingyException when you have declared Exception.
1- Declare the specific checked exceptions that your method can throw
public void foo() throws Exception { //Incorrect way
}
Always avoid doing this as in above code sample. It simply defeats the whole purpose of having checked exception. Declare the specific checked exceptions that your method can throw. If there are just too many such checked exceptions, you should probably wrap them in your own exception and add information to in exception message. You can also consider code refactoring also if possible.
2- Always catch only those exceptions that you can actually handle
catch (NoSuchMethodException e) {
throw e; //Avoid this as it doesn't help anything
}
Well this is most important concept. Don’t catch any exception just for the sake of catching it. Catch any exception only if you want to handle it or, you want to provide additional contextual information in that exception. If you can’t handle it in catch block, then best advice is just don’t catch it only to re-throw it.
3- Avoid using Throwable class
Throwable is the superclass of Exception and Error, as far as I know you need to use Throwable when you want to deal with both exceptions and errors, but it's definitely not your concern here, most of the java code deal with Exception and it's the way to go whenever you need to deal with checked exceptions http://docs.oracle.com/javase/tutorial/essential/exceptions/index.html.
**
Well if I was you I would do something like :
public void Do() throws BlahIsFoundException{
try {
if (blah) throw new BlahIsFoundException(...);
Thingy thingy = ...;
Foo(thingy);
} catch(EmptyThingyException exception) {
//Handle the exception correctly, at least log it
} finally {
//Do some clean up if needed, for example close a database connection or free some resources.
}
}
public void Foo(Thingy thingy) throws EmptyThingyException {
if (thingy == null ||
thingy.isEmpty()) throw new EmptyThingyException();
...
}
public class EmptyThingyException extends Exception { ... }
public class BlahIsFoundException extends Exception { ... }
Hope that helps, here are some good documents to read :
http://docs.oracle.com/javase/tutorial/essential/exceptions/index.html
http://howtodoinjava.com/best-practices/java-exception-handling-best-practices
It is designed in Java that I get a Throwable object if I invoke getCause() on an Exception.
I understand that getCause() is simply inherited from Throwable and I know that Throwable can be either an Error or an Exception, but a programmer generally should work only on the Exception level without dealing with Throwable/Error classes.
What was the reason in the Java exception hierarchy design to, for example, not include getCause() in the Exception class that would return an Exception object?
Here is an illustration of the inconvenience taken from Java Concurrency In Practice (Brian Goetz):
public class Preloader {
private final FutureTask<ProductInfo> future =
new FutureTask<ProductInfo>(new Callable<ProductInfo>() {
public ProductInfo call() throws DataLoadException {
return loadProductInfo();
}
});
private final Thread thread = new Thread(future);
public void start() { thread.start(); }
public ProductInfo get()
throws DataLoadException, InterruptedException {
try {
return future.get();
} catch (ExecutionException e) {
Throwable cause = e.getCause();
if (cause instanceof DataLoadException)
throw (DataLoadException) cause;
else
throw launderThrowable(cause);
}
}
}
It is said in the book:
...but also because the cause of the ExecutionException is returned as a Throwable, which is inconvenient to deal with...
And in launderThrowable() it is dealt with rethrowing Error right away (because we don't want to deal with it) and returning RuntimeException:
public static RuntimeException launderThrowable(Throwable t) {
if (t instanceof RuntimeException)
return (RuntimeException) t;
else if (t instanceof Error)
throw (Error) t;
else
throw new IllegalStateException("Not unchecked", t);
}
getCause is a method defined in Throwable, and simply inherited in Exception. The cause of a Throwable is simply a Throwable (it could be an Exception or an Error).
IMO, having a method, say getCauseAsException, that just returns an Exception if any as the cause exception is not really useful. You could simply invoke getCause() and check if it's an instance of Exception if you're just concerned with Exception and not Errors.
First, if you have a type that has a few subtypes, and their behavior is really the same, it makes sense to define the methods at the parent class. Basically, what the designers are saying is: "Throwable can have a cause, which is also a throwable, and you can get that cause". And you can do that in both Exception and Error because they both happen to be throwables.
Now, the Throwable hierarchy exists since Java 1.0, and generics didn't exist there. Nowadays you might be able to have defined the behavior like this:
class ModernThrowable<T extends ModernThrowable<T>> {
T getCause() {...}
}
And you could define ModernException as extends ModernThrowable<ModernException> and then you could get the sort of behavior that you expect.
But this design didn't exist back then, so you get a Throwable back, and you have to cast it. That's how things used to work and you have to keep backward compatibility.
But actually... as plausible as this may sound, this is not true. At least, it's not the whole truth.
It is perfectly OK to get an Error as the cause of an Exception. Take a look at javax.management.RuntimeErrorException. When you are working with an agent, you might get an Error, which in these special circumstances, should not cause you to abort the system immediately. So you put it as the cause of this special Exception. And thus, your getCause() will actually return an Error from an Exception.
So if it wasn't designed like this, you would have to go through hoops - have a specialty method just for the cause of this particular exception.
Programmers generally work at the Exception level when they are implementing applications. But remember that the JVM, for instance, is also implemented in Java and, in this context, programmers should work at the Throwable/Error level too.
So the question of at which level in the exception hierarchy tree you should work its more of an issue of the domain of the system you're implementing, than an issue of the language design itself. So it makes perfect sense from a language design perspective to provide the getCause method in the Throwable class, which is the root of the hierarchy tree. Since the Exception class inherits this method from its superclass, it's not necessary to provide the same method with a different return type just because in some specific domains you don't/shouldn't work with Throwable instances.
I'm developing a library and in some method I want to throw a ClassNotFoundException but eclipse force me to either 'Add a throws declaration' or 'Surround with try/catch'. I do not want to implement any of them, what I want is to throw this excepcion to the client of the class. I've seen that all classes that extend ReflectiveOperationException force me to add or surround the exception. In the other hand I've seen that classes that extend RuntimeException does not require to add or surround the exception.
As an abstraction of my problem, imagine a code like this:
public Class getClassForCellType(int cellTypeRequested) {
Class cellClassRequired = null;
if (cellTypeRequested == 0) {
cellClassRequired = CellA.class;
} else if (cellTypeRequested == 1) {
cellClassRequired = CellB.class;
} else {
throw new ClassNotFoundException("cellType Not Available");
}
return cellClassRequired;
}
I want to throw ClassNotFoundException because is what is happening and I would not like to use another more generic class. Someone could please explain me why those ReflectiveOperationException classes require handling them directly.
I think your problem arises because you are not using ClassNotFoundException for the purpose it is intended. This exception is very specifically intended to be thrown when the implementation of a requested Java class is not available on the classpath.
Here you are trying to translate a parameter into a Class, but that is not the same as the system level error of a missing Class definition.
I would create your own CellTypeClassNotResolvedException which extends RuntimeException and throw that instead:
public CellTypeClassNotResolvedException extends RuntimeException {
public CellTypeClassNotResolvedException(String s) {
super(s);
}
}
Eclipse is telling you (as any Java compiler must do) that if you want a ClassNotFoundException to be able to escape your method, the method must declare that that is a possibility, like so:
public Class getClassForCellType(int cellTypeRequested) throws ClassNotFoundException {
// ...
throw new ClassNotFoundException("cellType Not Available");
// ...
return cellClassRequired;
}
This is the rule for any Exception other than java.lang.RuntimeException and its subclasses.
You need to add a throws declaration due to ClassNotFoundException being a checked exception. TO fix your code, it would look like this:
public Class getClassForCellType(int cellTypeRequested) throws ClassNotFoundException {
Class cellClassRequired = null;
if (cellTypeRequested == 0) {
cellClassRequired = CellA.class;
} else if (cellTypeRequested == 1) {
cellClassRequired = CellB.class;
} else {
throw new ClassNotFoundException("cellType Not Available");
}
return cellClassRequired;
}
In Java, we have two core types of exceptions:
Checked, and unchecked exceptions.
Checked exceptions: If this type of exception is thrown, it has to be explicitly handled by either the client of the method or the method itself. ReflectiveOperationException is an example of this. These types of exceptions are usually used to reflect API problems, usage problems, legitimate/business application failures.
Java's way of fulfilling this requirement is to say you either have to handle (i.e. catch the exception) in your method, or you have to explicitly inform the client that they may get this exception (i.e. throws clause).
Unchecked exceptions: If this type of exception is thrown, it does not have to be handled explicitly. These are usually reflective of programming errors - for instance, ArrayIndexOutOfBoundsExceptions is a good example - you wouldn't anticipate running into this problem, and if you did, you can be relatively confident it's a bug and don't expect the client to cater for it in their code!
In your example, you are trying to tell the client that they passed you a bad parameter by throwing the ClassNotFoundException. They need to know this might be thrown in order to handle the scenario in their code, hence you need to add the throws declaration to the method signature.
public Class getClassForCellType(int cellTypeRequested) throws ClassNotFoundException {
}
See Oracle Docs on more exception tutorials: http://docs.oracle.com/javase/tutorial/essential/exceptions/index.html
In the past I'd read tons of code with methods like:
public Object doSomething() throws Throwable {
...
}
Is it common practice to do that?
What are pros & cons?
throws Trowable seemed to me like the "Agent Orange" way of getting the Exception- matter done
EDIT
Handle expected Exceptions in the Method
Throw unexpected Exceptions (one by one)
Don't care of Errors
Is that the way to go?
You should not throw Throwable. Here's why.
Throwable is the top of the hierarchy of things that can be thrown and is made up of Exceptions and Errors. Since Errors by definition arise from unsalvagable conditions, it is pointless to include them in your method declaration. That leaves just Exception.
You should declare your method with throws Exception instead.
Note that the narrower the range of throws the better.
Declaring your method to be throws Exception is ok if your method doesn't generate the exceptions, but instead calls other code that is declared as throws Exception and you want exceptions to percolate up the call stack.
If your method is the generating the exception, then declare a narrower range, eg throws IOException, MyProcessingException, etc
That's a loaded question. This isn't so much about exception handling as it is about code readability.
It depends where you get your code samples from. Professionals prefer to be more specific when throwing out of a method. The main reason is that it keeps your APIs more readable. For example, if your method throws Throwable, that basically means anything could happen and your method doesn't want to deal with it, no matter what. But really, only a limited number of things could happen:
Whatever checked exceptions resulting from other calls you are making in your method
Whatever checked exceptions you are throwing on purpose based on your own assertions
Whatever unchecked exception you didn't plan for
Errors (java.lang.Error) that are more global to the JVM and the environment
By specifically stating the exceptions you want to throw, you are telling the users of your API about what they should beware of. For example, when you use InputStream, you'll notice most methods throw at least java.io.IOException, which gives you some useful information about what you should watch for.
When coding, as a general rule, you want to try to keep your APIs as expressive as possible. You've got essentially one line of code to show the public API of a method (i.e. its signature, annotations too I guess), so you want it completely expressive (return type, name, parameters, but also the thrown exceptions).
As far as catching the throwables and printing the stack trace, I'd say that you should not catch the exception unless you can do something about it. Instead, let it roll up the call stack until some class catches it to do something about it. Sometimes, it may roll all the way up to your main class, which I guess would have to catch it and print the stack trace as last resort. Basically, if you can't act upon the exception, then let it go up the call stack. Also it is extremely rare that you find yourself in a situation where you should silence an exception (i.e. catch it but do nothing about it). That's usually inviting problems when comes time to troubleshoot issues.
Here is a fun but interesting article around misuse of exception handling in general.
In some rare cases it is acceptable to throw Throwables. For example, #Around advices in Spring AOP are usually declared to throw a Throwable.
The following example is copied verbatim from Spring AOP docs:
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.ProceedingJoinPoint;
#Aspect
public class AroundExample {
#Around("com.xyz.myapp.SystemArchitecture.businessService()")
public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
// start stopwatch
Object retVal = pjp.proceed();
// stop stopwatch
return retVal;
}
}
Why is doBasicProfiling declared to throw a Throwable? Because the original method (i.e. the execution join point), might throw an Error, RuntimeException, or a checked exception. So it only makes sense to declare doBasicProfiling to throw a Throwable.
Functionally, it is equivalent with throws Exception, since errors are unchecked.
I see no reason to declare a method to throw Throwable. However, this doesn't mean that catch and printStackTrace is a good alternative.
Usually, you want to catch throwables where you can do something sensible with them.
Code that throws a throwable you don't expect should explode gloriously, so you can see the error and fix the bug.
Is it common practice to do that?
In the JDK it is rare. This is mostly used when it is not clear how to handle checked exceptions.
What are pros & cons?
The pros is that you get your code to compile without worrying about checked exception.s
The cons is that exception you should be handling are being ignored.
Isn't it better to catch and printStackTrace()?
Unhandled exception are usually printed anyway so catching them doesn't help much.
You should catch an exception when you can add some value by doing so and add the exception to the throws clause when you can't.
It is really debatable matter.
Having method throwing too many exceptions will result in lot of error handling code. Some times it is not intended.
But because I don't like too many exception in signature does not mean that Lets use Parent of all exceptions and we are done!! It will not work.
What one can do is categorise exceptions such as BusinessException,ServiceException so that if you have a business rule which says that minimum balance in account can not be less than say 100$ then InsufficientBalance exception will be generated which will be child of BusinessException
so you method will be like
public Object doSomething() throws BusinessException {
if(!hasMinimumbalance())
{
throw new InsufficientBalance(ErrorCode);
}
}
What this will do is club related exceptions together and whenever API user wants to detect exception specific error then he can do it, else generic error handling is possible.
The core point here is on the UI you should display to the user that You have run out of balance and you can not withdraw money
You can say on the larger aspect to display human readable form of error it is really necessary to have separation of exceptions.
Are you asking about Throwable specifically? If so, then it's not good practice. It doesn't provide any useful information to class (method) user.
Throwing (and catching) Throwable (or Exception) is generally bad practice because it 'blankets' any specific exceptions you might want to catch. Then you would have to resort to ugliness like below:
public void myMethod() throws Throwable {
if (x) {
throw new MyException1();
}
if (y) {
throw new MyException2();
}
}
public void callingMethod() {
try {
myMethod();
}
catch(Throwable t) {
if (t instanceof MyException1) {
// handle exception 1
}
else if (t instanceof MyException2) {
// handle exception 2
}
else {
// handle other exceptions
}
}
}
Which is error prone (and flagged by CheckStyle as a code violation). It is much preferrable to have code like this:
public void myMethod() throws MyException1, MyException2 {
if (x) {
throw new MyException1();
}
if (y) {
throw new MyException2();
}
}
public void callingMethod() {
try {
myMethod();
}
catch(MyException1 e) {
// handle exception 1
}
catch(MyException2 e) {
// handle exception 2
}
}
Handling an exception just by calling printStackTrace() is usually not a good idea. printStackTrace() sends the stacktrace to standard error, which may not be read at all. A better option is to use the application's logging facility (like log4j) to report the exception. Even then, just logging it might no be enough.
My rule of thumb is:
If you can handle an exception locally, do so. For example when parsing a String as an Integer you could catch the NumberFormatException and return a default value:
prvate int parseAmount(String amountValue) {
int amount;
try {
amount = Integer.parseInt(amountValue);
}
catch(NumberFormatException e) {
// default amount
amount = 0;
}
return amount;
}
If you cannot handle an exception locally, consider if you should expose the exception type that is being thrown. If this type is some obscure (implementation-dependent) type, then wrapping it in your own generic exception type is probably a good idea:
private Customer getCustomer(int customerId) throws ServiceException {
try {
return customerService.getCustomer(customerId);
}
catch(CustomerServiceSpaghettiTangledException e) {
throw new ServiceException("Error calling the customer service", e);
}
}
Here 'ServiceException' is a subclass of Exception created by you. Spring also offers an exception hierarchy specifically for this purpose.
By wrapping the exception you hide the implementation details, making your service layer much simpler to use.
If you decide to throw an exception from your method, you will need to handle it 'higher up' in the callstack. This can be a generic error page in your web application stating that something went wrong and possibly providing an error message or code. In some cases the higher level code can attempt a retry or possibly an alternative way to obtain the required result.
The only use case I can think of would be for test code like unit tests. But Adam's counterpoint still stands "If so, then it's not good practice. It doesn't provide any useful information to class (method) user."