Java casting an exception (not class cast exception) - java

When an exception is caught in java is there a use case for casting the exception to a new type? Or is the standard
throw new DiffException(e)
The only way to do it. I apologize if I'm overlooking something but the only search results I get are for "ClassCastExceptions" Which is obviously not what I'm looking for

I believe you meant 'exception wrapping'.
There's no other way to do it - you create a new instance of Exception using a constructor which takes another exception as cause. This works thanks to 1-arg constructor of java.lang.Exception. The typical implementation of custom exception type (like your DiffException) declares such 1-arg constructor too.

Well, if the exception caught (e in your case I suppose) is a subtype of DiffException, you could of course cast it like
throw (DiffException) e;
but I doubt that's what you want to do, since it doesn't make a difference (the e will still have the same runtime type, even in the receiving end).
So the answer is most likely, no, there is no other, equivalent way, of doing
throw new DiffException(e);
than doing just that.
It should be noted however, that doing new DiffException(e) is not called casting but, wrapping, or chaining the exception.

If I understand you correctly here is the use case I am thinking about.
expression:
new FileInputStream("the path");
may throw FileNotFoundException if the file does not exist. FileNotFoundException extends IOException, so you could write code like:
public void readFromFile(String path) {
InputStream in = new FileInputStream(path);
// do something....
}
Now you can call this method as following:
try {
readFromFile("myFile");
} catch (IOException e) {
if (e instanceof FileNotFoundException) {
FileNotFoundException fnfe = (FileNotFoundException)e;
// do something
}
// do something else
}
But I'd recommend you create separate catch blocks for FileNotFoundException and for IOException (at least for this use-case):
try {
readFromFile("myFile");
} catch (FileNotFoundException e) {
// do something with FileNotFoundException
} catch (IOException e) {
// do something with IOException
}
This code does not contain instanceof, casting and other ugly stuff.

Since you mentioned use cases, the common one in Java is wrapping a checked exception as unchecked; this is appropriate when there's no way the checked exception can occur, such as here:
public static Reader getUTF8Reader(InputStream is) {
try {
return new InputStreamReader(inputStream, "UTF-8");
} catch(UnsupportedEncodingException e) {
// should never happen since UTF-8 is guaranteed to be available as per
// http://download.oracle.com/javase/6/docs/api/java/nio/charset/Charset.html
throw new RuntimeException("UTF-8 not available", e);
}
}
Without wrapping the exception, you'd either have to swallow it (which feels wrong) or declare the method as throws UnsupportedEncodingException which forces anyone using it to catch the exception that will never be thrown. Wrapping it, there's no onus on the caller to handle unlikely cases, yet we're protected in the unlikely event that UTF-8 isn't available on some obscure platform in the future.

Related

Throwing both main exception and sub-type, is there a proper way?

Okay, so I have a bunch of exception related questions across SO and Programmers, but there's just so much to ask, and either I don't know what to type, or not that many people have asked.
So, let's say I have a method that throws a FileNotFoundException (FNFE). I then have another method that uses the first one, but also throws a IOException (IOE).
My handler would catch both and do different things with each, but my IDE (IntelliJ) is signaling I have "a more general exception, 'java.io.IOException', in the throws list already".
I know it works if I do this:
public File openOrCreate(String pathStr) throws FileNotFoundException,
IOException {
try {
// Method that generates the FNFE
Path path = ReposioryProposition.getPath(pathStr);
File file = path.toFile();
catch (FileNotFoundException fnfe) {
throw fnfe;
}
if (!file.exists())
file.createNewFile(); // IOE
return file;
}
But do I need to do it explicitly? Will it work without, or more dangerously, will sometimes work without the explicit version.
To make sure we are on the same page, this is how I initially wrote the thing:
public File openOrCreate(String pathStr) throws FileNotFoundException,
IOException {
Path path = ReposioryProposition.getPath(pathStr);
File file = path.toFile();
if (!file.exists())
file.createNewFile();
return file;
}
But I am unsure what happens, is the FNFE thrown or swallowed up ? My intention is to catch them separately and do different stuff for one over the other.
You only have to include the more general exception in your throws list. This already specifies that the method may throw any subclass of this exception.
In particular, you must handle the more general exception anyway, and this exception handler will also handle the subclass. If you want to handle the subclass explicitly, you have to catch it before the more general exception:
try {
...
}
catch (FileNotFoundException e) {
// handle subclass
}
catch (IOException e) {
// handle general exception (this will not be executed if the
// exception is actually a FileNotFoundException
}
It's perfectly fine to omit the FileNotFoundException from the throws clause if you already have IOException in it.
Doing so doesn't affect the behaviour at all. FileNotFoundException will still be thrown, and you can catch it explicitly (as well as also having a different, more general, catch of IOException).
Having IOException in the throws clause simply states that IOException or any of its subclasses will be thrown from this method. FileNotFoundException is included in that.
Here is what Java Language Specification has to say:
If the run-time type of V is assignment compatible with (ยง5.2) a
catchable exception class of any catch clause of the try statement,
then the first (leftmost) such catch clause is selected. The value V
is assigned to the parameter of the selected catch clause, and the
Block of that catch clause is executed, and then there is a choice:
...
(Emphasis and ellipsis mine).
Therefore, if you want your more specific catch clause to be executed, you have to place it first in the catch list.
But do I need to do it explicitly? Will it work without, or more dangerously, will sometimes work without the explicit version.
Yes. You have to do it explicitly, because it is a checked exception.
Directly throwing back the exception:
If you just add those checked exception to your methods signature, meaning if you add throws clause in method heading like throws IOException, then you need not to catch anywhere in your method.
But doing this has one flaw, If you are accessing n files line by line in your code and each line may throw IOException, if the exception is raised. You must close the file .close() before throwing it back to the called method. So using only this throws clause will not let you to do it.
So, just catch the exception and do necessary action either in catch or finally block.
Only if no action is needed from your side and also if you want the exception to be popped out to the called method and the called method handles it, only then add the throws signature to the method.
you can catch first the sub class exception if not, then the general exception class like this
try{
// something
} catch(FileNotFoundException fne){
// Handle the exception here
} catch(IOException ioe) {
// Handle the IOException here
}

Java 1.5 compatible pattern that will handle all possible exceptions without exception swallowed/lost and resources closing?

I have some method that uses some resources that should be closed at the end and the method itself and resource closing could throw everything including IO Connection and so on exceptions, some Runtime exceptions and even Errors (everything what inherits Throwable OOM is often case.).I want to handle all Exceptions without losing information and to send/throw the most important exception to the client (supposingly the runtime exceptions/errors?) This is the pattern I use (it's java 1.5 so I can't use resource features from 1.7):
Throwable thr=null;
try {
methodThatCouldThrowCheckedExceptionAndErrorAndRuntimeExcpetion();
log("method succesfully executed.");
} catch (IKnowThisException ikte) {
//Exception will be not lost
log("Method was not executed ,and I can suggest further actions",itke);
thr=ikte;
} catch (Throwable t) {
// This exception will be not lost too
log("Method was not executed ,and I don't know why.",t);
thr=t;
} finally {
try{
// The method below - of course contains the standard null checkers.
closeResourcesMethodThatCouldThrowEverythingToo();
log("resources were closed.");
} catch (IKnowThisEscpetionToo iktet) {
log(iktet);
throw new IllegalStateException("Resources were not closed , because of the known exception and I can suggest some actions" , ijtet);
} catch (Throwable t) {
log(t);
throw new IllegalStateException("Resources were not closed and I don't know why" , t);
}
// in case resources are closed we can re-throw exception from try{} block
if ( thr != null ) {
throw thr;
}
}
But I'm not completely sure it's the best approach .Here a similar approach i sused . But it does not handle unchecked exceptions (do I need to handle them?) Is there a case when I can lost valuable information? In the most examples I found nothing special is done about Errors/RuntimeExcpetions , but I want them logged. Is there a better approach? May be I should construct a more complicated chained exception to keep information compacted?
To preserve all of the errors, it would be best to use a custom exception class, that provides something like ARM's "suppressed exception" collection.
If the method throws an exception, this is the (cause of the) main exception. If closing resources raises additional exceptions, they are added to the main as suppressed exceptions.
If the method completes without failure, but closing resources raises an exception, the first becomes the main exception, and subsequent resource close failures are added to it as suppressed exceptions.
If a resource was intended to have side effects like writing a file or updating a database, the application needs to determine what to do when closing that resource fails. Using a general purpose mechanism that hides those resource closure exceptions would not allow the application to make that determination, and would only be useful in the rare cases where the application doesn't care if any output is actually produced.
I would look at how the compiler rewrites the try-with-resources pattern in Java 1.7. Below is a simple example of the pattern in source level 1.7, followed by a decompiled version with try-with-resources sugaring disabled:
// Original:
public void test() throws IOException {
try (final StringWriter writer = new StringWriter()) {
writer.write("This is only a test.");
}
}
// Decompiled:
public void test() throws IOException {
final StringWriter writer = new StringWriter();
Throwable t = null;
try {
writer.write("This is only a test.");
}
catch (Throwable t2) {
t = t2;
throw t2;
}
finally {
if (writer != null) {
if (t != null) {
try {
writer.close();
}
catch (Throwable t2) {
t.addSuppressed(t2);
}
}
else {
writer.close();
}
}
}
}
Sadly, the addSuppressed() method was only introduced in Java 1.7, but you could create a custom exception class that introduces this behavior, as #erickson suggests in his answer. If only one exception occurs, simply rethrow that one. Otherwise, replace it with the custom exception, wrap the original as the cause, and add any suppressed exceptions that occurred during closing of resources.
As I know, un-checked exception should not be handle. But you can handle by catching broader exception such as "Exception" before finally block.
I suggest you read my blog post Clean Up After Yourself (Grab my Close class) and then
import static com.frischcode.util.Close.close;
// Where ... is any number of things to close (in finally block - naturally).
close(...);

Idiom to let a specific exception bypass a broad catch block?

Often, when implementing a template method or interface method, you can only throw one specific type of exception defined by the method. But your implementation may make class to API's that throw an incompatible exception type, or many different exception types.
Naturally you need to catch them and wrap the exceptions into the type suitable for the implemented method signature. Lets assume we want to implement this interface:
public interface SomeDataGetter {
public long getSomeData() throws IOException;
}
Our implementation makes use of some other API product to implement this, and the API method we are calling may have this signature:
public long loadFromDBOrCache(Object ... params) throws SQLException, IOException, ObjectNotFoundException, RuntimeException, FridayException, NotWeekendException, NumberIs42Exception;
I made this up to demonstrate the case where you can't exactly enumerate all the possibly thrown exceptions by concrete type. Do note that IOException is a type we are allowed to throw from our implementation.
Now I can go the lazy route when implementing this and wrap anything to fit my signature:
#Override
public long getSomeData() throws IOException {
try {
return loadFromDB(...);
} catch (Exception e) {
throw new IOException(e.getMessage(), e);
}
}
This will obviously wrap any exception into an IOException (even an IOException) and it works out ok. But I'd like to not wrap IOExceptions, since I am allowed to throw those without wrapping them:
#Override
public long getSomeData() throws IOException {
try {
return loadFromDB(...);
} catch (IOException e) {
throw e;
} catch (Exception e) {
throw new IOException(e.getMessage(), e);
}
}
You can imagine this gets cumbersome quickly if there are multiple possible exception in the implementation and multiple exceptions you are allowed from the implementation. I need an extra catch for each exception I want to pass throgh.
Whats the best idiom to keep that readable (also, I'm lazy, and don't want to write all these extra catches) and still avoid unneccessary exception nesting? Or shoud I not bother and just wrap everything?
One approach would be making a method that wraps all "prohibited" exceptions in an allowed one, while returning all the allowed ones unwrapped, like this:
private static void throwIoException(Exception e)
throws IOException // <<= Add other "allowed" exceptions here
{
if (e instanceof IOException) {
throw (IOException)e;
}
... // <<= Add checks for other "allowed" exceptions here
throw new IOException(e.getMessage(), e);
}
Now you can use a single catch block, and do the wrapping as needed:
try {
return loadFromDB(...);
} catch (Exception e) {
throwIoException(e);
}
One unpleasant consequence of this is that the stack trace shows the utility method at the top of the newly created IOException, but that's not important, because the real exception is the wrapped one, not the IOException wrapper. If the exception that you caught happens to be IOException, the correct stack trace should remain in place.
I would consider the lazy route of wrapping all exceptions you get into IOExceptions (or another checked exception) to be a bad practice. Instead I would consider wrapping the exceptions in runtime exceptions, thereby bypassing the catch or specify requirement. E.g.
#Override
public long getSomeData() throws IOException {
try {
return loadFromDB(...);
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}
The reason why this is better is that checked exceptions carry a certian meaning. If you catch for instance a ParseException in your code and rethrow that as a IOException you are lying. As a user of your code I might be able to do something about certain types of checked exceptions, but if you obfuscate the true cause of an exception it will be more difficult to debug the code when an error occurs.
In general I think you should minimize the use of checked exceptions since it litters error handling code throughout your application. Also if you are using someone else's code you have no guarantee that a RuntimeException won't be thrown anyway (unless you carefully read through it all). Therefore you have to consider that possibility anyway and handle it somewhere so your application don't crash. The virtues of unchecked exception vs checked exceptions has been discussed quite a lot elsewhere here and here for instance.

Rethrowing checked exceptions

public void foo() {
begin();
try {
...
commit();
} catch (Exception e) {
rollback();
throw e;
}
}
In the sample above, there is an error because foo has no throws Exception. Adding that wouldn't make do the method's usability a lot of good either.
What's the best way to do this? How do you do something if an error occurs without really "handling" the error?
Since Java 8 we use
/**
* 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
}
You can rethrow a checked exception, but only by avoiding the compilers checked exception validation.
public void foo() throws MyCheckedException {
begin();
try {
...
commit();
} catch (Exception e) {
rollback();
// same as throwing an exception without the compiler knowing.
Thread.currentThread().stop(e);
}
}
Before you use stop() you should read http://download.oracle.com/javase/6/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html
Thread.currentThread().stop(e) .. is behaviorally identical to Java's throw operation, but circumvents the compiler's attempts to guarantee that the calling method has declared all of the checked exceptions that it may throw:
At least two approaches come to mind, which are usually going to be combined depending on what you want foo to do:
1. Catch and rethrow only the relevant exceptions
There are only so many exceptions the code in your main flow can throw (probably mostly SqlExceptions). So only catch and rethrow those, and declare that you're doing so. More to the point, rethrow only the ones you're not actually handling (in your simplified sample code, you're not handling any, but your real life code is probably more subtle).
Mind you, some of the exceptions may be runtime exceptions, and so you may want to combine this with the below.
2. Don't catch the exception at all
Like this:
// Signature changes to include any exceptions that really can be thrown
public void foo() throws XYZException, ABCException {
// A flag indicating that the commit succeeded
boolean done = false;
begin();
try {
// Don't have any `return` statements in here (or if you do,
// set `done` to `true` first)
...
commit();
done = true; // Commit didn't throw an exception, we're done
} finally {
// finally clause always happens regardless
if (!done) {
// We must be processing an exception; rollback
try {
rollback();
} catch (Exception e) {
// quash it (e.g., leave this block empty), we don't want
// to mask the real exception by throwing a different one
}
}
}
}
Naturally your signature needs to include any exceptions that may be thrown in the main flow, but that's what you're trying to do, if I'm understanding you correctly.
Again, you may well combine these two approaches, because you may want to handle some exceptions and not others.
Wrap it with some RuntimeException which is unchecked.
Adding that wouldn't make do the method's usability a lot of good either.
No. It will be good at documentation, also caller will take care handling it.
Also See
exception-thrown-inside-catch-block-will-it-be-caught-again
throws-or-try-catch
I'd say that in this case rolling back is handling the exception appropriately. It's one of the few cases where it's legitimate to catch and re-throw.
Simply catching and logging an exception is not what I would consider handling. Rather than rethrowing, in that case I'd rather see checked exceptions added to the method signature and let it bubble up.
you may throw a subclass of RuntimeException - they don't require a catch()
the key point is, why should you throw a new Exception from a catch block.
if you use catch then handle your exception there in your catch. If you have to inform the caller method with an exception, then don't catch the exception with try-catch, instead, sign your method with throws and let the caller catch the e xception.
or throw a RuntimeException, i find this idea less useful because of lack of readability, then you don't need to sign your method with throws.
Here you've chanced on one of the biggest religious schisms in the Java, ( if not wider ) , world. It boils down to those that feel, as TJ seems to, and I do too, that checked exceptions are valuable for many reasons, VS the Rod Johnson/Spring school that in the design of Java, checked exceptions were used in many instances where they shouldn't, say closing a resultset or socket, so because it was wrongly used in many cases, it makes them useless so all exceptions should be unchecked. There are many classes in the Spring framework that are very thin wrappers around standard Java objects, but convert checked exceptions to unchecked. It drives me berserk!
Anyway, put me down as strongly agreeing with everything TJ has said, but know that you'll probably never find a "right" answer.
It's worth mentioning some advances in this area.
First, in Java 7, it's possible to catch and throw generic exceptions, as long as what's declared inside the try block is caught or declared in the outer block. So this would compile:
void test() throws SQLException {
try {
conn.commit();
} catch (Throwable t) {
// do something
throw t;
}
}
This is well explained here : http://docs.oracle.com/javase/7/docs/technotes/guides/language/catch-multiple.html
Another way is described here : http://blog.jooq.org/2012/09/14/throw-checked-exceptions-like-runtime-exceptions-in-java/
The reason you may want to use that has often to do with lambdas, or throwing exceptions from some generic methods. I ran into this when I wanted to replace repeating constructs of:
try {
do_operation
flag_success
} catch (Throwable e) {
flag_error
throw e;
}
With using a method of:
public static void wrapExec(RunnableT s) {
try {
s.run();
flag_success
} catch (Throwable t) {
flag_error
doThrow(t);
}
}
and therefore replacing the whole try/catch block with just
wrapExec(()->{do_operation})

Suppress-catch or throw exceptions which can never occur?

Say I have the following line in a method:
String encodedString = URLEncoder.encode(foo, "utf-8");
this method throws an UnsupportedEncodingException. Which is better:
/** #throws UnsupportedEncodingException umm...never
*/
public void myMethod() throws UnsupportedEncodingException {
...
String encodedString = URLEncoder.encode(foo, "utf-8");
...
}
(forcing the caller to catch this himself) Or:
public void myMethod() {
try {
...
String encodedString = URLEncoder.encode(foo, "utf-8");
...
catch(UnsupportedEncodingException e) {
Logger.log("cosmic ray detected!");
}
}
Or is there a more elegant way of handling exceptions which can't really ever occur?
Never say never ;)
In the example above you could always catch the exception then throw a RuntimeException:
public void myMethod() {
try {
...
String encodedString = URLEncoder.encode(foo, "utf-8");
...
} catch(UnsupportedEncodingException e) {
throw new RuntimeException("This should not be possible",e);
}
}
That way the caller isn't forced to catch something you 99.999% sure will never happen, but in the crazy event that it does happen you still get an exception bubble up to a point where you'll hopefully notice it and be able to quickly realize what's changed and fix it.
HTH
If you can pretty much guarantee that the exception can never occur, then it's better to localize this assertion at the narrowest scope rather than letting it propagate, because other people may not realize that this is the case without looking at documentations.
If a method is declared to throw something, then there should be scenarios where it actually does. If it's pretty much guaranteed to never does, then it's better to omit the throws clause altogether and simplify your API.
You should always throw exceptions appropriate to your level of abstraction (Effective Java 2nd Edition, item 61). Declaring that you might throw something, when it's guaranteed never to occur, breaks this design guideline.

Categories