performing clean up and passing the exception to the caller - java

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);
}

Related

Rethrow exception inside handleAsync() of CompletableFuture [duplicate]

This question already has answers here:
Why is throwing a checked exception type allowed in this case?
(3 answers)
Closed 1 year ago.
I am working on a function which takes a CompletableFuture<Object> and needs to handle its result (or its exception).
I am modifying it so that under a certain condition, I need to throw an exception.
However, the compiler tells me that I'm not handling this new exception (Unhandled exception ...).
The function looks like this:
In the line //<-- THIS IS NOT OK is what I'm just adding
In the line //<-- THIS IS OK is what was already there
Code:
public void myFunction(CompletableFuture<Object> resultSupplier, boolean someCondition) {
resultSupplier.handleAsync((result, throwable) -> {
if (throwable != null) {
//do something with the throwable
} else {
if (someCondition) {
throw new Throwable("some throwable"); //<-- THIS IS NOT OK ("Unhandled exception: java.lang.Throwable")
}
try {
//do something with the result which may raise an exception
} catch (Throwable ex) {
//do something in the catch
throw ex; //<-- THIS IS OK
} finally {
//do something to finalize
}
}
return null; //I don't actually need the future, just to execute the code above
});
}
I am having some troubles understanding this.
Why the compiler is ok rethrowing the caught throwable inside the try block, but it's not ok with re-throwing the throwable that I've added?
I must say that I understand more the compile error (I'm inside a BiFunction<> so I can't throw checked exceptions) rather than the compiler's happiness over the throw ex inside the catch block, but mostly I would just like to understand what's going on here and why there is a difference between the two.
P.s. you can copy-paste the code snippet into an IDE to easily reproduce the issue.
Please refer to answer\comment from #Slaw for answer.
INCORRECT ANSWER
The reason is Throwable is base class of Exception. If catching code only handles Exception it won't catch it. The other one where you are rethrowing, may be caught as Throwable but thrown as probably it's original type.
Usually, a good static code analysis would tell you both things are no-no - don't throw explicit Throwable instance and don't rethrow caught instance; instead just throw; to use it polymorphically.
EDIT
This is what I found:
If I change the line you mentioned from
throw new Throwable("some throwable");
To:
throw new Exception("some throwable");
compiler still cribs.
So does if I change code to:
try {
throw new Exception(); <=== change here
} catch (Throwable ex) {
//do something in the catch
throw ex; //<-- THIS IS OK
} finally {
//do something to finalize
}
The only way I can get the code to get compiled is when I use
throw new CompletionException(throwable);
It seems that CompletableFuture always deals with CompletionException so the only way for it to make happy is to wrap your throwable in CompletionException.

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!

Android Java - how to refactor out a try-catch-finally with a throw in the finally, all inside an abstract class?

Good afternoon,
I'm currently working with the code from:
https://github.com/kevinsawicki/http-request
I'm attempting to refactor the code as applicable to clear all the Android Studio warnings before I include it in a project I'm working on. Currently I'm working with the following nested abstract class:
///////////////////////////////////////////////////////////////////////////////////////////////
protected static abstract class Operation<V> implements Callable<V> {
protected abstract V run() throws HttpRequestException, IOException;
protected abstract void done() throws IOException;
public V call() throws HttpRequestException {
Log.d(TAG, "in HttpRequest nested class Operation call");
boolean thrown = false;
try {
return run();
} catch (HttpRequestException e) {
thrown = true;
throw e;
} catch (IOException e) {
thrown = true;
throw new HttpRequestException(e);
} finally {
try {
done();
} catch (IOException e) {
if (!thrown) {
throw new HttpRequestException(e);
}
}
}
}
} // end Operation
This is producing the following warning for having a throw inside a finally block:
I've been looking at this for a while but I can't seem to find a way to factor out this warning. I did see this other answer:
throws Exception in finally blocks
However I would really prefer to not introduce another function. If I was to introduce a closeQuietly function, would that go inside or outside the nested class listed above? Please advise, thanks!
It's just a warning. If you read the explanation it says (emphasis mine)
While occasionally intended, such throw statements may mask exceptions thrown and tremendously complicate debugging.
If you need to do it, then do it, but just make sure it's actually what you want to do and understand the implications (it's akin to saying "do you really want to do this?!"). Not all of IntelliJ's warnings can be eliminated.
Edit based on follow up: You have to ask yourself if your framework needs to throw that exception in the finally block. You can implement a similar approach to what was linked without using another function (just replace the throw statement in finally with a log statement), but that might not be desirable. It depends entirely on the potential error conditions.
If, for example, you're expecting done() to run into issues whenever you've previously received an IOException or an HttpRequestException then you probably don't need to throw anything in the finally block (just log it). But, if you need to make sure you alert the user if something went wrong trying to clean up, then you do need to throw there and you should ignore the warning.
I suppose you could do something like this:
protected static abstract class Operation<V> implements Callable<V> {
protected abstract V run() throws HttpRequestException, IOException;
protected abstract void done() throws IOException;
public V call() throws HttpRequestException {
Log.d(TAG, "in HttpRequest nested class Operation call");
boolean thrown = false;
try {
return run();
} catch (IOException e) {
throw new HttpRequestException(e);
} finally {
try {
done();
} catch (IOException e) {
// handle the IOException
}
}
}
} // end Operation
If an HttpRequestException is ever thrown it'll be thrown by the method, you still transform the IOException into an HttpRequestException (not quite sure why you want to do that), and in the finally block you would need to catch and handle the IOException appropriately.

check condition using try and catch block-java

I understand the basic try-catch, where we put methods that could possibly throw exceptions in the try block. But when we need to check if something is wrong, and throw an exception, is it correct to use the code below? And the exception is caught, the program will continue to execute?
I can't tell why the try is needed here, but without it eclipse says 'syntax error'. Thanks for your help in advance!
public run (){
if (something !=true) {
try{
throw new Exception();
}catch (Exception e){
}
Yes that is correct. You have to use try since that is where the exception-throwing code is entered and where exceptions are caught (just using a catch block won't serve any purpose)
Generally speaking, exceptions are used to let the calling code handle errors in your method.
If you just want to handle the error in run, you don't need exceptions:
public void run() {
if (something != true) {
// handle it
}
}
If you want the calling code to handle the error instead, this is where you need exceptions:
public void run() throws Exception {
if (something != true) {
throw new Exception();
}
}
And where you call run, use a try/catch block:
try {
run();
} catch (Exception e) {
// handle it
}
It is also recommended that you don't throw an Exception instance, use a custom subclass instead.

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()

Categories