I had written a restful web service. The contract of the restful web service is to receive parameters, communicate to a external service via SSL and respond back to the client. There are no issues in the service contract and the service. The service design was good and all the checked exceptions have been caught in the catch block but after a few service testing, then it seemed that the unchecked exceptions are not handled properly. Is there are any way to encapsulate these unchecked exception using domain exceptions. To be simple, how to handle or anticipate the unchecked exceptions.
In the specific case of a restful web service, the framework has a 'catch-all' handler that does something you don't like. So, contra some other answers here, there's nothing evil about adding more or different handling. The framework's handler is certainly not cleaning up for you, so you can only make things better by cleaning up for yourself. Thus, you have two choices.
you can add an exception mapper to your list of providers, as per the JAX-RS standard.
You can wrap your code in a try/catch of Throwable, and then construct a Response that appeals to you in the catch handler.
Without knowing what toolkit you are using for JAX-RS I can't be more detailed about (1).
You should always have a single place in your code where you handle all exceptions and what you describe sounds like you have a mess of handling code all around, wherever a method is called that declares checked exceptions. Use this code in lower-level code that encounters checked exceptions:
try {
...
catch (RuntimeException e) { throw e;}
catch (Exception e) { throw new RuntimeException(e); }
And at the exception barrier (that central place mentioned) use
try {
...
catch (Throwable t) { // logging, returning error response, whatever
}
finally { // global resource cleanup
}
Doing more than this is required only in special cases, which you will find are not very common in the code base, and that is when your lower-level methods acquire resources additional to the resources already acquired for each request. An example could be file I/O. In such cases it is of course mandatory to use a try-finally to take care of that extra resource, but you still must not catch and swallow exceptions: the main exception barrier still needs to know there was a problem and do its cleanup.
RuntimeExceptions should indicate coding errors, so ideally you should fix the bugs rather than trying to handle them. Unfortunately some library developers misuse RTEs for non-bugs and force you to catch them. You can wrap a RuntimeException in an Exception.
....
catch (RuntimeException e) {
throw new MyCheckedException("Failed to...", e);
}
EDIT: It seems it's a controversial view these days. I know that bad checked exceptions can be a pain. But good use of checked exceptions helps clients and implementers to understand the contract. Using RuntimeExceptions for non-bugs may make it easier to work with an API in the 'happy case', when you don't care about exceptions, but much harder to know what to expect of the 'sad case' when you do. It also makes it harder for implementers of interfaces to know what's expected of them - which RuntimeExceptions they are or aren't allowed to throw etc.
Related
This question already has answers here:
What issues may ensue by throwing a checked exception as a RuntimeException?
(6 answers)
Closed 9 years ago.
In Java it is observed that there is a convention of re-throwing a RuntimeException just after handling a Checked Exception.
This way has both good and bad consequences. When the compiler forces something to be handled via a Checked Exception, the developer can just get rid of it by catching it and re-throwing it as a RuntimeException.
Can someone explain if this scenario can be considered as a good practice? If so, would this approach be less error prone or would it make the code base unstable?
Actually it is the incompetent attempts at handling checked exceptions which result in an unstable code base. Typically, you'll have this:
try {
//stuff
} catch (IOException e) {
log.error("Failed to do stuff", e);
throw e;
}
and then next level up you'll have to deal with it again, typically logging it all over and making a mess of the log files. It will be even worse if you don't rethrow:
try {
// do stuff
} catch (IOException e) {
return null;
}
Now the calling code has no idea something went wrong, let alone what. Compared to those attempts, this actually accomplishes exactly what the application logic needs:
try {
// do stuff
} catch (IOException e) {
throw new RuntimeException(e);
}
Now the exception can freely propagate up the call stack until it reaches the well-defined exception barrier, where it:
aborts the current unit of work;
gets logged at a single, unified spot.
In a nutshell, to decide whether to catch-and-handle or catch-and-rethrow, just ask yourself this question:
Must the occurrence of this exception abort the current unit of work?
if yes: rethrow an unchecked exception;
if no: provide meaningful recovery code in the catch-block. (No, logging is not recovery).
From many years of real-life experience I can tell you that more than 90% of all possible checked exceptions are of the "aborting" type and need no handling at the place of occurrence.
Argument against the language feature of checked exceptions
Today, checked exceptions are widely recognized as a failed experiment in language design, and here's the key argument in a nutshell:
It is not up to the API creator to decide on the semantics of its exceptions in the client code.
Java's reasoning is that exceptions can be divided into
exceptions resulting from programming errors (unchecked);
exceptions due to circumstances outside of programmer's control (checked).
While this division may be real to some extent, it can be defined only from the perspective of client code. More to the point, it is not a very relevant division in practice: what truly matters is at what point the exception must be handled. If it is to be handled late, at the exception barrier, nothing is gained by the exception being checked. If handled early, then only sometimes there is a mild gain from checked exceptions.
Practice has confirmed that any gains afforded by checked exceptions are dwarfed by real-life damage done to real-life projects, as witnessed by every Java professional. Eclipse and other IDEs are to blame as well, suggesting inexperienced developers to wrap code in try-catch and then wonder what to write in the catch-block.
Whenever you encounter a method which throws Exception, you have found yet another living proof of the deficiency of checked exceptions.
The idea of checked exceptions is "Java only" - as far as I know, no language after Java adopted this idea.
There are too many checked exceptions which are caught ... and silently ignored.
If you look at Scala, they dropped it as well - it's only there for Java compatibility.
In this tutorial on Oracle's web site, you will find this definition:
If a client can reasonably be expected to recover from an exception, make it a checked exception.
If a client cannot do anything to recover from the exception, make it an unchecked exception.
This notion has been adopted in Scala as well, and it works fine.
Technically speaking your proposal works. Discipline and code reviews are required in either way.
The term "can just get rid of it" is not totally correct in this case. This is getting rid of exceptions:
try {
} catch (Exception e){
e.printStacktrace();
}
This is the most common bad practice among the try-catch use. You are catching the exception and then, just printing it. In this case, the catch block catches the exception and just prints it, while the program continues after the catch block, as if nothing had happened.
When you decide to catch a block instead of throwing an exception, you must be able to manage the exception. Sometimes exceptions are not manageable and they must be thrown.
This is something you should remember:
If the client can take some alternate action to recover from the
exception, make it a checked exception. If the client cannot do
anything useful, then make the exception unchecked. By useful, I mean
taking steps to recover from the exception and not just logging the
exception.
If you are not going to do something useful, then don't catch the exception. Re-throwing it as a RuntimeException has a reason: as stated before, the program just cannot continue as nothing happened. This way, a good practice would be:
try {
} catch (Exception e){
//try to do something useful
throw new RuntimeException(e);
}
This means: you just caught an Exception (like an SQLException) from which you can't recover without stopping and resetting the thread. You catch it, you try to make something in between (like resetting something, closing open sockets, etc...) and then you throw a RuntimeException().
The RuntimeException will suspend the whole thread, avoiding the program continue as if nothing have happened. Furthermore, you were able to manage the other exception without just printing it.
It may or may not be okay, depending on the context, but it probably is not.
As a rule of thumb RuntimeExceptions should only be used to indicate programming errors (examples include IllegalArgumentException and IllegalStateException). They don't have to be checked exceptions because you generally assume your program is correct until proven otherwise and you cannot handle these exceptions in a meaningful manner (you have to release an updated version of the program).
Another valid use of runtime exceptions is when you use a framework that will catch and handle the exception for you. In such a scenario it would only be burdensome to having to declare the exception in every method when you are not going to handle it anyway.
So generally speaking I would say re-throwing a checked exception as a runtime exception is very bad practice unless you have a framework that will handle it properly.
The general rule is: you throw a checked exception when the caller might be able to do some kind of recovery when informed about it. Otherwise, throw an unchecked exception.
This rule applies when an exception is first thrown.
But this also applies when you catch an exception and are wondering whether to throw a checked or unchecked exception. So there is no convention to throw a RunTimeException after catching a checked one. It is decided in a case-by-case basis.
One small tip: if you are going to just re-throw an checked exception after catching one and do nothing else, most of the time it is alright to just not catch the exception and add it to the exceptions thrown by the method.
I'm working with a very errant JNI that throws all sorts of exceptions that I need to catch somehow. (Some of them are as low-level as C++ reference cast exceptions!)
What I want to know is what the accepted (i.e. standard) idiom of catching all is in Java; akin to catch (...) in C++.
Up to now I've been using
} catch (java.lang.Exception e){
...
}
as I believed that was standard. But I've realised that it is, theoretically possible at least, to derive a class from java.lang.Throwable and throw that, in which case I should really use
} catch (java.lang.Throwable e){
...
}
Only I haven't seen that in source code before so perhaps it's idiosyncratic. Would would you guys do?
You can catch Throwable to catch absolutely everything that can be caught in Java, but note that doing so is rarely a good idea - you can actually interfere with the normal operation of the JVM. The Error hierarchy, which is the other part of the hierarchy deriving from Throwable, is used for really critical errors such as stack overflow, out of memory, or corrupted .class files. Catching them and not properly throwing them on is a very, very bad idea.
The other problem is that it is insufficient. If you have low-level programming errors in native code, i.e. on the far side of the JNI barrier, your program state may very well be corrupted beyond recovery, and the JVM might not even be able to correctly notice this and throw an exception - it might be corrupted beyond the ability to propagate exceptions.
If the code beyond the JNI bridge is faulty, your only real option is to fix that code. If that isn't an option (e.g. because you don't have access to the source), you have to sandbox the code completely. Write a native process that uses the native code and that you can communicate with somehow (stdin/stdout, networking, whatever), then launch that process from your Java program. If the process dies, it dies, but at least it can't take down your program with it.
Using catch(Throwable e) {.. } is the way to go. That is what I did in one of my application where JNI was used.
just catch Throwable, because this will catch everything.
Remember that Java has two fundamental exception types:
Exception, which is checked
RuntimeException which is not
you can make your own custom exception and use that exception to throw exception Throwable is parent class of all exceptions
It depends on whether you want to catch just Exception, or both Exception and Error (through use of Throwable).
As it says in the Error javadoc, you probably don't want to catch such things - but then again your situation may seem to warrant it if you know what you're going to do with caught Errors.
In my main code I usually always use a catch Throwable to make sure that I can get all error conditions and report it appropriately.
Throwable is the supper type of Exception.
Exception can catch all checked exceptions
I've seen here many general questions about the difference between Exception and Throwable. I know the difference, and I have a more specific question.
I'm writing a library that binds and runs together several user-supplied pieces of code. If one of the pieces fails, the whole computation is discarded. In order to keep resource usage clean, users can also supply finalizers that are run when such an event happens. The patterns is something like this:
try {
// process ...
} catch (Exception ex) {
runRegisteredFinalizers();
throw ex;
}
My question is: Should I intercept and rethrow just Exceptions like above, or should I also intercept Throwables? If an Error occurs, is there any chance that
JVM will recover? (So is there any point running finalizers?)
JVM will be in such a state that it's actually possible to run them?
Also, when running finalizers, I catch and ignore their exceptions so that other registered finalizers have a chance to run, something like:
try {
finalizer.run();
}
catch (Exception ex) {
log.error("Exception in a finalizer", ex);
}
Again, should I intercept just Exceptions, or also Throwables? Ignoring and not rethrowing Errors seem more problematic.
Maybe the safest thing to do would be to catch Throwable (or Exception and Error separately) and pass in the reference of what was caught to your runRegisteredFinalizers() giving the user a chance to decide if it is something they should care about.
However, errors that you would be catching would be either specific to your toolkit (not necessarily from the users code), or things that the user did not account for (assuming they would have trapped the case themselves). In these cases, the type of exception doesnt matter.
In either case though, depending on the nature of your toolkit and the potential impact on missing a Error, it might make sense to catch that as well.
I believe that if you're dealing with user supplied code that you can assume nothing about, then you should catch throwable (in both cases), consider linkage errors that don't affect the whole system, just the executing code like: NoSuchMethodError or NoClassDefFoundError
If you want to give up in case of an error effecting the whole system then you can not catch or rethrow Errors that extends VirtualMachineError like OOME.
I have to download some URLs, and it can happen that during the operations some exception may occur, like java.net.NoRouteToHostException. I consider it a temporary error exception, as the download can succeed if you retry it after some time.
So, I'd like to catch all those exceptions related to temporary errors, and I've started with these: java.net.NoRouteToHostException, java.net.SocketException
Can you list other exceptions like these?
java.net.SocketException is the parent of java.net.NoRouteToHostException so you could maybe catch only the parent. The others childs of SocketException are BindException, ConnectException and PortUnreachableException. Maybe it's ok to catch only SocketExceptionin your case...
One pattern which is sometimes useful for dealing with transitory errors on retry-able operations is to define an error-callback interface and some classes that implement it; when an error occurs, let the callback object know, and let it decide whether an exception should be thrown or the action should be retried. Because the existing communications classes don't follow such a pattern, it may be necessary to catch their exceptions and turn them into callbacks.
Note that this approach allows much cleaner handling of many error-handling scenarios than would normal exception handling. Among other things, it makes it easy to set policies for how many retries may be attempted, how long they may take, etc. and also provides a means of skipping future retries if something like a "cancel" request is received.
As #reef has already said java.net.NoRouteToHostException exntends java.net.SocketException, so if you catch java.net.SocketException it is enough. But java.net.SocketException extends IOException and I think that this is what you really should to catch. All IO problems should throw this exception.
HttpRetryException is another. Maybe everything in java.net that does not extend SocketException?
One quick (and very dirty) way could be
try {
....
} catch(Exception e) {
if(e.getClass().getPackage().getName().equalsIgnoreCase("java.net")) {
retry();
}
}
Why is the catch(Exception) almost always a bad Idea?
Because when you catch exception you're supposed to handle it properly. And you cannot expect to handle all kind of exceptions in your code. Also when you catch all exceptions, you may get an exception that cannot deal with and prevent code that is upper in the stack to handle it properly.
The general principal is to catch the most specific type you can.
Short story: it's called bug masking. If you have a piece of code which is not working well and throwing exceptions (or you pass malformed input to that piece of code) and you just blind your eyes by catching all possible exceptions, you will actually never uncover the bug and fix it.
You should only catch exceptions if you can properly handle them. As you cannot properly handle all possible exceptions you should not catch them :-)
It depends on what you need. If you need to handle different types of exceptions in different ways then you should use multiple catch blocks and catch as much specific exceptions as you can.
But sometimes you may need to handle all exceptions in the same way. In such cases catch(Exception) may be ok. For example:
try
{
DoSomething();
}
catch (Exception e)
{
LogError(e);
ShowErrorMessage(e); // Show "unexpected error ocurred" error message for user.
}
Because you don't really know why an exception happened, and several exceptions require very special car to be handled correctly (if possible at all), such as a OutOfMemoryException and similar low-level system exceptions.
Therefore, you should only catch exceptions:
which you know exactly how to deal with it (e.g. FileNotFoundException or so)
when you will re-raise them afterwards (for instance to perform post-fail cleanup)
when you need to transport the exception to another thread
I find two acceptable uses of catch(Exception):
At the top level of the application (just before returning to the user). That way you can provide an adequate message.
Using it to mask low-level exceptions as business ones.
The first case is self-explanatory, but let me develop the second:
Doing:
try {
// xxxx
} catch(Exception e) {
logger.error("Error XXX",e)
}
is bug masking like #dimitarvp said.
But the below is different:
try {
// xxxx
} catch(Exception e) {
throw new BusinessException("Error doing operation XXX",e)
}
This way you aren't ignoring bugs and hiding them under the carpet. You are providing a high-level exception with a more explanatory message to higher application layers.
It's also always important to manage exceptions at the correct layer. If you escalate a low-level exception to a high business layer, it's practically impossible for the higher layer to manage it well.
In that case, I prefer to mask the low level exceptions with a business one that provides a better context and message and that also has the original exception to be able to go into the details.
Even so, if you can catch more concrete exceptions and provide better treatment for them you must do it.
If in a block of code you can get an SQLException and a NetworkException you must catch them and provide adequate messages and treatment for each of them.
But if at the end of the try/catch block you have an Exception mapping it to a BusinessException it's ok for me.
In fact, I find it adequate when higher service layers only throw business exceptions (with details inside).
Besides what yet answered by #anthares:
Because when you catch exception you're supposed to handle it properly. And you cannot expect to handle all kind of exceptions in your code. Also when you catch all exceptions, you may get an exception that cannot deal with and prevent code that is upper in the stack to handle it properly.
The general principal is to catch the most specific type you can.
catch(Exception) is a bad practice because it catches all RuntimeException (unchecked exception) too.
This may be java specific:
Sometimes you will need to call methods that throw checked exceptions. If this is in your EJB / business logic layer you have 2 choices - catch them or re-throw them.
Catching specific exception classes means you will need to re-analyze your actions for which exceptions can be thrown when you look to see how this code handles exceptions. You will often get into a "what if..." situation and it can be a lot of effort just working out if exceptions are handled correctly.
Re-throwing means that code calling your EJBs will be littered with catching code that will typically not mean anything to the calling class. n.b. throwing checked exceptions from EJB methods will mean that you are responsible for manually rolling back any transactions.
But sometimes it is OK! Like if you have a piece of code that does something 'extra', which you really don't care about, and you don't want it to blow up your application. For example, I worked on a large application recently where our business partners wanted a certain daily transaction to be summarized in a new log file. They explained that the log wasn't all that important to them, and that it did not qualify as a requirement. It was just something extra that would help them make sense of the data being processed. They did not need it, because they could get the information elsewhere. So that is a rare case where it is perfectly fine to catch and swallow exceptions.
I also worked at a company where all Throwables were caught, and then rethrown inside a custom RuntimeException. I would not recommend this approach, but just pointing out that it is done.
Isn't it another valid scenario to ensure that a thread keeps alive catching exception inside it?
Thread shouldRunWhenApplicationRuns = new Thread() {
#Override
public void run() {
try {
// do something that should never end
} catch (Exception ex) {
// log it
}
};
shouldRunWhenApplicationRuns.start();
Sonar has also a good Explanation, why this is not a good idea, and how it can be prevented:
https://rules.sonarsource.com/java/RSPEC-2221
Catching Exception seems like an efficient way to handle multiple possible exceptions. Unfortunately, it traps all exception types, both checked and runtime exceptions, thereby casting too broad a net. Indeed, was it really the intention of developers to also catch runtime exceptions? To prevent any misunderstanding, if both checked and runtime exceptions are really expected to be caught, they should be explicitly listed in the catch clause.