Proper way to handle Runtime Exceptions in Java - java

I'm completely new to this code and begun to questions the design choices of the original developers.
I have a multi-threaded Java application that processes a number of tasks. My job is to fix the exception handling in the code so that when a RuntimeException occurs (iBatis and/or NullPointerException) the rest of the tasks are executed instead of the thread terminating. I want to know what is the best way to deal with the exception handling below:
public List<WorkUnit> performModule(List<WorkUnit> listOfInputs)
throws ModuleException {
List<WorkUnit> listOfOutputs = new ArrayList<WorkUnit>();
for (WorkUnit mi : listOfInputs) {
WorkUnit mo=null;
try {
if (mi instanceof BulkOrder) {
mo = performModuleOperation(...);
} else if (mi instanceof Order) {
mo = performModuleOperation(...);
} else if (mi instanceof PreReleaseLoad) {
mo = performModuleOperation(...);
} else if (mi instanceof Load) {
mo = performModuleOperation(...);
}
listOfOutputs.add(mo);
} catch (OMSException e) {
if (e.shouldProcessFurther()) {
listOfOutputs.add((mo!=null) ? mo : mi);
}
//save error to database - code was removed
if ( e.getExceptionType().equals(ExceptionType.TECHNICAL)) {
if ( e instanceof ModuleException ) {
throw (ModuleException) e;
} else {
throw new ModuleException(e);
}
}
} catch (Throwable th) {
ModuleException me = new ModuleException(th);
ExceptionHandler.logException(me, (WorkUnit)mi,orderDelegate);
throw me;
}
}
return listOfOutputs ;
}
I have two major problems. 1) The catch for the Throwable object. I understand that they want to capture checked exceptions and unchecked exceptions. I guess that they want to check for Errors as well but the Sun documentation for exception handling specifically states that this is highly advised against. In the event you get a really serious error like the JVM running out of memory you may not be able to recover. This could be caught in a log file and I don't agree with it needing to be dealt with. Personally if you are tracking technical and applications exceptions errors doesn't seem like something that you would monitoring like any other exception. I could be wrong...
2) It isn't clear how the exceptions are being handled. In the code below the, which the exception throws to the code above it wraps a regular exception be it checked or unchecked into a custom exception and throws that. The code above looks for an OMSException which is the parent of every custom exception in the entire application. Is this a good design? You can see where they include a ExceptionType to the custom exception object. There already seems to be an functionality built into the existing exception handling of Java. If it is an application exception then throw a custom exception. If it is a technical exception, something is null when it isn't suppose to be or a database connection problem, then catch a unchecked exception from Java and react accordingly. This whole thing seems confusing. I just want to know what thoughts other have on the whole thing.
public Order performModuleOperation(Order order)
throws ModuleException {
try {
Map<String, Rule> rules = ...
}
catch (InductException ie) {
throw ie;
}
catch (Exception e) {
e.printStackTrace();
throw new InductException(e.toString(),e);
}
return order;
}

There are two ways to deal with a thread that exits with an unchecked exception. The first option is to run the thread from with in a try-catch block that catches all errors and exceptions:
Thread t = new MyThread();
try {
lauchThreadHere(t);
} catch (Throwable e) {
// log `e` or re-launch thread `t` or do something else.
}
Another way is to implement Thread.UncaughtExceptionHandler:
public class MyUeh implements Thread.UncaughtExceptionHandler {
public void uncaughtException(Thread t, Throwable e) {
// log `e` or re-launch thread `t` or do something else.
}
}
Thread t = new MyThread();
t.setUncaughtExceptionHandler(new MyUeh());
lauchThreadHere(t);

Related

How to make sure that exceptions do not lose its stack trace information in java?

Recently, I met some exception problem in java, which reminded me of the typical idiom recommended by Bruce Eckel:
Converting checked to unchecked exceptions
The real problem is when you are writing an ordinary method body, and you call another method and realize, "I have no idea what to do with this exception here, but I don’t want to swallow it or print some banal message." With chained exceptions, a new and simple solution prevents itself. You simply "wrap" a checked exception inside a RuntimeException by passing it to the RuntimeException constructor, like this:
try {
// ... to do something useful
} catch (IDontKnowWhatToDoWithThisCheckedException e) {
throw new RuntimeException(e);
}
This seems to be an ideal solution if you want to "turn off the checked exception—you don’t swallow it, and you don’t have to put it in your method’s exception specification, but because of exception chaining you don’t lose any information from the original exception.
This technique provides the option to ignore the exception and let it bubble up the call stack without being required to write try-catch clauses and/or exception specifications.
However, I found it didn't work in some cases. as seen here:
package exceptions;
// How an exception can be lost
class VeryImportantException extends Exception {
#Override
public String toString() {
return "A very important exception";
}
}
class HoHumException extends Exception {
#Override
public String toString() {
return "A trivial exception";
}
}
public class LostMessage {
void f() throws VeryImportantException {
throw new VeryImportantException();
}
void dispose() throws HoHumException {
throw new HoHumException();
}
public static void main(String[] args) {
try {
LostMessage lm = new LostMessage();
try {
lm.f();
} catch (VeryImportantException e) {
throw new RuntimeException(e);
} finally {
lm.dispose();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}/* Output:
Exception in thread "main" java.lang.RuntimeException: A trivial exception
at exceptions.LostMessage.main(LostMessage.java:36)
Caused by: A trivial exception
at exceptions.LostMessage.dispose(LostMessage.java:23)
at exceptions.LostMessage.main(LostMessage.java:33)
*///:~
As the output demonstrated, the second exception completely obliterates the first one. There is no record of the first exception in the exception stack trace, which can greatly complicate debugging in real systems. usually, it’s the first exception that you want to see in order to diagnose the problem.
Joshua Bloch recommends the try-with-resource way that a resource must implement the AutoCloseable interface, which process is somewhat complex.
So, my question is this: is there any way I can use to make sure that exception will not lose its stack trace information by Bruce Eckel's approach?
You might want to consider using try-with-resource instead of a finally block. It tends to handle this situation more like it sounds you would want the situation handled. See this article for more details.
Alternatively, you could simply eat the exception (as Andy Thomas's answer shows), or (if you want to know about both exceptions that were thrown) you could combine the exceptions into a single kind of Aggregate Exception.
The problem isn't that you're wrapping the exception. The problem is that you're replacing it with a subsequent, unrelated exception thrown from the finally block.
One easy way to avoid this is to not throw an exception from the finally block.
For example:
try {
LostMessage lm = new LostMessage();
try {
lm.f();
} catch (VeryImportantException e) {
throw new RuntimeException(e);
} finally {
try {
lm.dispose();
} catch ( HoHumException e ) {
// No-op or logging
//
// If we're exiting this try-finally because an exception
// was thrown, then don't allow this new exception to replace it.
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}

How to wrap checked exceptions but keep the original runtime exceptions in Java

I have some code that might throw both checked and runtime exceptions.
I'd like to catch the checked exception and wrap it with a runtime exception. But if a RuntimeException is thrown, I don't have to wrap it as it's already a runtime exception.
The solution I have has a bit overhead and isn't "neat":
try {
// some code that can throw both checked and runtime exception
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
Any idea for a more elegant way?
I use a "blind" rethrow to pass up checked exceptions. I have used this for passing through the Streams API where I can't use lambdas which throw checked exceptions. e.g We have ThrowingXxxxx functional interfaces so the checked exception can be passed through.
This allows me to catch the checked exception in a caller naturally without needing to know a callee had to pass it through an interface which didn't allow checked exceptions.
try {
// some code that can throw both checked and runtime exception
} catch (Exception e) {
throw rethrow(e);
}
In a calling method I can declare the checked exception again.
public void loadFile(String file) throws IOException {
// call method with rethrow
}
/**
* Cast a CheckedException as an unchecked one.
*
* #param throwable to cast
* #param <T> the type of the Throwable
* #return this method will never return a Throwable instance, it will just throw it.
* #throws T the throwable as an unchecked throwable
*/
#SuppressWarnings("unchecked")
public static <T extends Throwable> RuntimeException rethrow(Throwable throwable) throws T {
throw (T) throwable; // rely on vacuous cast
}
There is a lot of different options for handling exceptions. We use a few of them.
https://vanilla-java.github.io/2016/06/21/Reviewing-Exception-Handling.html
Guava's Throwables.propagate() does exactly this:
try {
// some code that can throw both checked and runtime exception
} catch (Exception e) {
throw Throwables.propagate(e);
}
UPDATE: This method is now deprecated. See this page for a detailed explanation.
Not really.
If you do this a lot, you could tuck it away into a helper method.
static RuntimeException unchecked(Throwable t){
if (t instanceof RuntimeException){
return (RuntimeException) t;
} else if (t instanceof Error) { // if you don't want to wrap those
throw (Error) t;
} else {
return new RuntimeException(t);
}
}
try{
// ..
}
catch (Exception e){
throw unchecked(e);
}
I have a specially compiled .class file containing the following:
public class Thrower {
public static void Throw(java.lang.Throwable t) {
throw t;
}
}
It just works. The java compiler would normally refuse to compile this, but the bytecode verifier doesn't care at all.
The class is used similar to Peter Lawrey's answer:
try {
// some code that can throw both checked and runtime exception
} catch (Exception e) {
Thrower.Throw(e);
}
You can rewrite the same using instanceof operator
try {
// some code that can throw both checked and runtime exception
} catch (Exception e) {
if (e instanceof RuntimeException) {
throw e;
} else {
throw new RuntimeException(e);
}
}
However, your solution looks better.
The problem is that Exception is too broad. You should know exactly what the possible checked exceptions are.
try {
// code that throws checked and unchecked exceptions
} catch (IOException | SomeOtherException ex) {
throw new RuntimeException(ex);
}
The reasons why this wouldn't work reveal deeper problems that should be addressed instead:
If a method declares that it throws Exception then it is being too broad. Knowing that "something can go wrong" with no further information is of no use to a caller. The method should be using specific exception classes in a meaningful hierarchy, or using unchecked exceptions if appropriate.
If a method throws too many different kinds of checked exception then it is too complicated. It should either be refactored into multiple simpler methods, or the exceptions should be arranged in a sensible inheritance hierarchy, depending on the situation.
Of course there can be exceptions to the rule. Declaring a method throws Exception can be perfectly reasonable if it's consumed by some kind of cross-cutting framework (such as JUnit or AspectJ or Spring) rather than comprising an API for others to use.
I generally use the same type of code structure, but condense it down to one line in one of the few times a ternary operator actually makes code better:
try {
// code that can throw
}
catch (Exception e) {
throw (e instanceof RuntimeException) ? (RuntimeException) e : new RuntimeException(e);
}
This does not require additional methods or catch blocks which is why I like it.
lombok has this handled with a simple annotation on the method 😊
Example:
import lombok.SneakyThrows;
#SneakyThrows
void methodThatUsusallyNeedsToDeclareException() {
new FileInputStream("/doesn'tMatter");
}
In the example the method should have declared throws FileNotFoundException, but with the #SneakyThrows annotation, it doesn't.
What actually happens behind the scenes is that lombok does the same trick as the high rated answer to this same question.
Mission accomplished!

Java 8: How do I work with exception throwing methods in streams?

Suppose I have a class and a method
class A {
void foo() throws Exception() {
...
}
}
Now I would like to call foo for each instance of A delivered by a stream like:
void bar() throws Exception {
Stream<A> as = ...
as.forEach(a -> a.foo());
}
Question: How do I properly handle the exception? The code does not compile on my machine because I do not handle the possible exceptions that can be thrown by foo(). The throws Exception of bar seems to be useless here. Why is that?
You need to wrap your method call into another one, where you do not throw checked exceptions. You can still throw anything that is a subclass of RuntimeException.
A normal wrapping idiom is something like:
private void safeFoo(final A a) {
try {
a.foo();
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
(Supertype exception Exception is only used as example, never try to catch it yourself)
Then you can call it with: as.forEach(this::safeFoo).
If all you want is to invoke foo, and you prefer to propagate the exception as is (without wrapping), you can also just use Java's for loop instead (after turning the Stream into an Iterable with some trickery):
for (A a : (Iterable<A>) as::iterator) {
a.foo();
}
This is, at least, what I do in my JUnit tests, where I don't want to go through the trouble of wrapping my checked exceptions (and in fact prefer my tests to throw the unwrapped original ones)
This question may be a little old, but because I think the "right" answer here is only one way which can lead to some issues hidden Issues later in your code. Even if there is a little Controversy, Checked Exceptions exist for a reason.
The most elegant way in my opinion can you find was given by Misha here Aggregate runtime exceptions in Java 8 streams
by just performing the actions in "futures". So you can run all the working parts and collect not working Exceptions as a single one. Otherwise you could collect them all in a List and process them later.
A similar approach comes from Benji Weber. He suggests to create an own type to collect working and not working parts.
Depending on what you really want to achieve a simple mapping between the input values and Output Values occurred Exceptions may also work for you.
If you don't like any of these ways consider using (depending on the Original Exception) at least an own exception.
You might want to do one of the following:
propagate checked exception,
wrap it and propagate unchecked exception, or
catch the exception and stop propagation.
Several libraries let you do that easily. Example below is written using my NoException library.
// Propagate checked exception
as.forEach(Exceptions.sneak().consumer(A::foo));
// Wrap and propagate unchecked exception
as.forEach(Exceptions.wrap().consumer(A::foo));
as.forEach(Exceptions.wrap(MyUncheckedException::new).consumer(A::foo));
// Catch the exception and stop propagation (using logging handler for example)
as.forEach(Exceptions.log().consumer(Exceptions.sneak().consumer(A::foo)));
I suggest to use Google Guava Throwables class
propagate(Throwable throwable)
Propagates throwable as-is if it is an
instance of RuntimeException or Error, or else as a last resort, wraps
it in a RuntimeException and then propagates.**
void bar() {
Stream<A> as = ...
as.forEach(a -> {
try {
a.foo()
} catch(Exception e) {
throw Throwables.propagate(e);
}
});
}
UPDATE:
Now that it is deprecated use:
void bar() {
Stream<A> as = ...
as.forEach(a -> {
try {
a.foo()
} catch(Exception e) {
Throwables.throwIfUnchecked(e);
throw new RuntimeException(e);
}
});
}
You can wrap and unwrap exceptions this way.
class A {
void foo() throws Exception {
throw new Exception();
}
};
interface Task {
void run() throws Exception;
}
static class TaskException extends RuntimeException {
private static final long serialVersionUID = 1L;
public TaskException(Exception e) {
super(e);
}
}
void bar() throws Exception {
Stream<A> as = Stream.generate(()->new A());
try {
as.forEach(a -> wrapException(() -> a.foo())); // or a::foo instead of () -> a.foo()
} catch (TaskException e) {
throw (Exception)e.getCause();
}
}
static void wrapException(Task task) {
try {
task.run();
} catch (Exception e) {
throw new TaskException(e);
}
}
More readable way:
class A {
void foo() throws MyException() {
...
}
}
Just hide it in a RuntimeException to get it past forEach()
void bar() throws MyException {
Stream<A> as = ...
try {
as.forEach(a -> {
try {
a.foo();
} catch(MyException e) {
throw new RuntimeException(e);
}
});
} catch(RuntimeException e) {
throw (MyException) e.getCause();
}
}
Although at this point I won't hold against someone if they say skip the streams and go with a for loop, unless:
you're not creating your stream using Collection.stream(), i.e. not straight forward translation to a for loop.
you're trying to use parallelstream()

performing clean up and passing the exception to the caller

I need to do some initialization and clean it up in case of any exception. I'd still like the exception to be passed to the caller. The problem is I now have to declare this method as throws Throwable and then I have to explicitly handle this throwable in the caller, just as if all procedures don't throw Throwables implicitly already. Stupid isn't it?
try {
init_step1();
init_step2();
}
catch (Throwable th) {
clean();
throw th;
}
One way of doing this is to perform the cleanup in a finally block instead, noticing whether there's been an exception by whether you actually got to the end of the try block or not:
boolean success = false;
try {
// Stuff here
success = true;
} finally {
if (!success) {
clean();
}
}
Stupid is fighting against checked exceptions. You have to throw something different if you don't want to require every caller to handle it. just throw a RuntimeException
public void myMethod() throws RuntimeException {
try {
init_step1();
init_step2();
}
catch (Throwable th) {
clean();
throw new RuntimeException(th);
}
}
why do you catch Throwable in first place anyway? init_step1() and init_step2() doesn't throw an exception?
#Jon Skeet's solution is the cleanest. Another solution which may interest you.
try {
// Stuff here
} catch(Throwable t) {
clean(t);
// bypasses the compiler check
Thread.currentThread().stop(t);
}
I would only suggest using this approach if you needed to know the exception thrown. e.g. For resources I have which are closable, I record the exception which triggered their close. This way if I try to use the resource and it is closed I can see why it is closed.
private void checkClosed() {
if (closed)
throw new IllegalStateException("Closed", reasonClosed);
}

Throwing a Linked List of Exceptions in Java

I have a function that loops while doing something that could throw an exception. Looks something like this:
public void myFunction() throws MyException {
while(stuff) {
try {
DoSomething() // throws an exception
}
catch (Exception ex) {
throw new MyException(some, stuff, of, mine, ex);
}
}
}
The error causing the exception is recoverable. It can be something like an SQL error in a single update statement where the while loop executes a series of update statements. Or a parsing error in a single piece of data, where the loop is processing multiple pieces of data. I need to pass the exception further up the chain so the GUI part of the program can process it, handle it and pass on the error to the user. But I don't want to kill the loop in this particular function. The other things it's doing might not be invalid. The error that caused the exception might not be fatal to the function.
So my question is this: Is it an acceptable practice to build linked lists of custom exceptions (where each exception is a node, and the exception thrown is the head of the list) and then throw the head of the list (if any) once the loop finishes?
Has anyone ever seen this done? Can anyone think of any potential problems with doing this? Can anyone think of other, better ways to handle the root problem: the need to pass up multiple unrelated exceptions with out exiting the function until it is done?
Here's an example of how the linking and throw might be implemented very simply:
public void myFunction() throws MyException {
MyException head = null;
while(stuff) {
try {
DoSomething() // throws an exception
}
catch (Exception ex) {
MyException tmp = new MyException(some, stuff, of, mine, ex);
tmp.next(head);
head = tmp;
}
}
if(head != null)
throw head;
}
My intial thought (other than I've not seen this) is that an exception is potentially quite a large object (containing the stacktrace) and I'd prefer not to store a lot of them.
I would instead build a list of the erroneous parameters/arguments as exceptions occur, and upon completion of the loop, throw a custom exception populated with this list (if the list has more than 0 elements). That would seem a more manageable way of handling this scenario.
public void myFunction() throws CustomException {
List<MyError> errors = new ArrayList<MyError>();
while(stuff) {
try {
DoSomething() // throws an exception
}
catch (Exception ex) {
errors.add(new MyError(some, stuff, of, mine, ex));
}
}
if (errors.size() > 0) {
throw new CustomException(errors);
}
}
Do you really need to throw all the exceptions? How do you expect to the individual, unrelated exceptions to be handled? Generally in cases like this, the system will just report the errors and be done with it.
If so, you might want to just collect the error messages and add them to a custom Exception class and throw that.
If those exceptions are really unrelated to each other so that you can't take benefit of get/setCause(), then I would rather collect this information in one MyException.
E.g.
public void myFunction() throws MyException {
MyException myException = null;
while(stuff) {
try {
DoSomething() // throws an exception
}
catch (Exception ex) {
if (myException == null) {
myException = new MyException();
}
myException.addException(some, stuff, of, mine, ex);
}
}
if (myException != null) {
throw myException;
}
}
Update: Brian handles exactly this approach in a more neat manner. I would opt for that instead :)
Actually throwing any exceptions from such a function is probably not the right way to handle this if it is expected that there will be errors. I'd suggest to either return a List (Array) of all exceptions/errors that occured or better to provide a error handler object to the function that can deal with the exceptions. i.e.:
public interface ErrorHandler
{
public void handleError( Throwable ex /*, add some context info */ );
}
public void myFunction( ErrorHandler eh )
{
while(stuff) {
try {
DoSomething() // throws an exception
}
catch (Exception ex) {
if( eh != null )
eh.handleError( ex );
}
}
}
This also lets the error handler either collect the errors to present them to the user or to decide that the whole batch operation has become void because of some error and to throw a exception of it's own to abort the processing early.
If the exception thrown by DoSomething(); could cause the very same method to throw another exception; this might be a problem. In other words, if DoSomething(); throws an exception because you didn't handle the previous one, there might be unnecesarry error to handle.
I think you can pass some callback or listener to the method, or set in a class variable and instead of a throw the list, like x4u did.
In Java there is an interface for this already: java.beans.ExceptionListener
IMO, an exception should be the last resource you have for handling an error. It should be avoided if possible. So, you might want to pass the error description (create error codes, pass the message, or something meaningful) to the GUI, and not the exception itself.

Categories