I would like to know if there is a way where we can get notified when a certain exception has been thrown even if it was already caught.
I have an exception which is caught by the underlying framework which threw the exception. I have been trying to use this exception from outside of their try-catch (surrounding it essentially) as a trigger point to run some code and trying to find a way to do it.
Any way to do it?
Thanks!
You gave no context, so here some possibilities:
set a breakpoint in the appropriate constructor and run in debug mode
use aspects, e.g. aspectj or spring
put your extensions in the exception's constructor
put a try-catch around the code that causes the exception
P.S.: for the case you didn't know, you can catch RuntimeExceptions the same way you catch checked exceptions.
If an exception is already caught by the framework, there is no way of you catching it with a try-catch block.
You're trying to do this:
try {
try {
throw new Exception();
} catch(Exception e) {
e.printStackTrace();
}
} catch(Exception e) {
System.out.println("Caught from the outside!");
}
which will fail, the exception's StackTrace will be printed, but the "Caught from the outside!" will not be printed. This is due to the fact that the exception thrown in the middle has already been caught, exceptions cannot be caught twice, or that would defeat the purpose of error handling; once an error is handled, no need to notify higher levels about it ;)
From what I understand, you have no access to the source, the exception is caught and handled outside of your scope of access, and you want to make it do something?
The only solution that's immediately apparent to me is PowerMock, a library allows you to override constructors and return objects of your own creation. It's typically only used in testing, and I discourage using it for any other purpose, but you could use it to replace all instances of that exception with an extension of the original exception, with your own code added in.
Related
Disclaimer : I'm coming from C# world so this is question might be biased by my previous experience
I have a method that is initializing logging. If this fails, the rest of the app should not run as any call to logger will throw a NullPointerException.
Today, my code is catching the exception and printing an error log via System.err. To me, this is a mistake, it should let the exception propagate up until it kills the app.
So I started removing the try catch and I suddenly got complains from the compiler saying that I should declare my exception on the whole stack where this method is called.
I understand the logic behind it and used to found it practical : you know how this method is capable of failing.
However, that doesn't sound right to me in term of separation of responsibility. I don't want the upper layers to be aware of this potential IOException fail, it is a very specialized behavior that shouldn't be known to , for example, the main method.
And, if we push this logic, it means that :
the highest layer will eventually have to declare the whole scope of exceptions (From IO to Network to custom exceptions...)
Any addition of a new exception can potentially impact a lot of files and code
Am I missing something or this is intended exception design ?
I think what you are looking for is not a Java Exception, it is a Java Error.
An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions. The ThreadDeath error, though a "normal" condition, is also a subclass of Error because most applications should not try to catch it.
https://docs.oracle.com/javase/7/docs/api/java/lang/Error.html
You can throw a error, which indicates that your app won't work anymore, which you declared as correct behaviour.
You can encapsulate your checked exception in a RuntimeException (or one if its children), which does not force you to declare the exception:
public X execute() {
try {
return someThrowingMethod();
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
If you can't initialize the logger and this is an enterprise application, I recommend killing your application with an exit code that explains the reason. If this is a client application, I recommend showing a message to the client stating the problem, recommending to the client that you report this back to you, and allowing them the choice of whether to proceed or not
I started learning Java and I got confused about the necessity of try-catch blocks in some cases.
Let's say I have the following in my code:
System.out.println(args[0]);
If I don't have any arguments, I get the following error:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at Main.main ...
But I wondered why do I need a try-catch block, with e.printStackTrace() in it, if the output will be the same as above and I also could identify the problem?
The purpose of try-catch blocks is NOT to have a simple e.printStackTrace() on them, but to manage possible exceptions on the code within.
By requiring a try-catch block, Java is forcing you to deal with the exceptions that can happen in your code and make a decision on what to do with them, in order to allow your code to fail gracefully.
Moreover, if you capture an exception with a catch, code can continue to execute after, which does not happen if the exception is not captured.
It is not necessary to catch all exceptions. In Java there is two types of exceptions: checked and unchecked. The rule is simple a checked exception has to be handled by the caller while an unchecked exception can be handled either by not catching it, or by catching it.
In your case since ArrayIndexOutOfBoundsException is an unchecked exception, you don't necessarily have to catch it . However if it is not handled your application will crash. Sometimes you want to save your app in case of an error, and in this case catching the exception is the way to do it. E.g: You ask an url from the user and try to connect to it. If the URL was invalid it will throw an exception. But instead of letting your application to crash you might want to notify the user and ask a new URL. So you will catch the exception and do the error handling.
Basically, to do a simply e.printStackTrace() is a bad practice. Do real error handling on the catch block or throw it away.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I have been coding in Java for work but everything I know about Java comes from googling how to do anything whenever I need to know. I have done C/C++ at school before and now I'm just getting into exception handling in Java.
In Java, why should we specify the exception type in the catch block? What are some advantages to doing so? What are some disadvantages to just using Exception instead of, say "IOException"?
Also when should I use the try/catch block when coding? I noticed that I got into the pattern of just coding the logic part, and I only add try/catch if an error shows while coding telling me to add it, or when I run the code and the program quits halfway because of an exception, then I find where it happens in the code and add the try/catch block there to "handle the exception" in order to get the code keep running. Is this how people normally decide where to add in try/catch? Is there a more efficient way such as "when doing certain things in code, add try/catch"?
Thanks a lot!
EDIT:
When should I use try/catch blocks and when should I use private void method() throws Exception? What's the difference between the two besides the syntax?
A lot of relatively new programmers have this thought that all exceptions are bad, but this isn't true. Exceptions are neither good or bad. They just provide information.
Take NullPointerExceptions vs FileNotFoundExceptions.
Generally (not always), if a NullPointerException is thrown, it means that there was a bug in your code somewhere. You forgot to initialize a variable, didnt check to see if a flag was true, etc. When these exceptions are thrown, you generally want your program to fail and crash, because it encountered unexpected behavior. You want the failure to be loud and obvious, because if the program didn't fail immediately after a null pointer, the program might get really wacky, and you would have a hard time finding the problem.
However, FileNotFoundExceptions are generally the opposite.
Imagine if at some point in your program, you prompted the user for a file. The user may or may not input a valid file, but the program shouldn't crash here either way. Instead, the user should be notified if the file can't be found, and prompted again. This is generally why you have catch blocks, so if that exception gets thrown, you can handle it and continue (by displaying your dialog/message/whatever).
However, if a NullPointerException was thrown here, you would definetly want your program to crash (as it's probably a bug in your code). This is why catch blocks force you to specify the Exception, so you can deal with some (such as FileNotFoundException), and let others through (such as NullPointerException)
Generally, you want to catch exceptions if your program is capable of recovering from that exception. This is (supposed to be) why java forces you to try/catch certain exceptions. Most of those exceptions are meant to be exceptions your program should be able to recover from (although sometimes, you would want to fail instead, either by declaring that your method throws that exception, or wrapping the caught exception in a RuntimeException).
I might be leaving out details I am unfamiliar with myself. But as far as I know specifying the specific exception type, allows you to get more detailed info on the error in the log.
Also eclipse and other ide's usually show a warning when it's "proper" to use try/catch blocks.
Hope it answers the question to some extent
The point of specifying which exceptions to catch is fairly straight forward. The main thing to remember is that Exceptions are classes, and have an inheritence hierarchy. For example, IOException inherits from Exception. This allows you to catch different exceptions, and handle them in different ways.
try {
....
} catch (IOException e){
logger.fatal("An IO Exception occurred.");
} catch (NullPointerException e){
logger.info("A null pointer exception occurred.");
}
In the above example, an IO exception will be logged as fatal, but a null pointer is only logged at the info level. Any exceptions that may be thrown besides these two will not be caught, and will be thrown to the next level of error handling. This could either crash your program, or a method higher up the call chain may handle the thrown exception.
try {
....
} catch (IOException e){
logger.fatal("An IO Exception occurred.");
} catch (NullPointerException e){
logger.info("A null pointer exception occurred.");
} catch (Exception e) {
logger.fatal("An unexpected exception occurred.");
}
In this second example, all exceptions are caught. Only one catch block will be executed though (The first one that matches).
A good way to plan when writing code is to:
1) Determine if this line of code can fail. (IO, parsing text, calling a service...).
2) If this code fails, do I want to handle this failure here (with a catch block) or later, by throwing the exception up the call chain.
You should specify the type of the exception in most cases because methods you call may throw different types of exceptions. For example, let's say you're trying to access a file in the file system, when you call the method to do this, the method can throw a FileNotFoundException which as the name describes, you will get when the file path you gave it does not exist. The method could also throw an IOException if the file does exist, but there's some other problem with the IO device or the file itself.
Usually, you would want to know the difference between these two errors and act accordingly, in which case you will have to put two catches, one for FileNotFoundException and another for IOException.
If for some reason you don't care about the specific error, then you simply put one catch for a regular Exception.
For the answers to your other questions, you can find them here http://docs.oracle.com/javase/tutorial/essential/exceptions/index.html
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.
Also,
does the default handler catches an exception thrown by us? If yes, then does it depend on whether the exception is checked or not?
Any Throwable can be caught. But subclasses of Error are not intended to be caught by user application code. They still can be caught, but some errors may even leave application in bad state (OutOfMemoryError for example).
A catch block will catch any sub-type of the declared Throwable type. For example catch (Exception ex) {} will handle any Exception that is thrown in the try block, as even RuntimeException (un-checked) is a child.
Note that this will not catch instances of Error, since they are not a sub-class of exception. If you really want a catch all, you can use something like catch (Throwable th). This is not advisable, since Error's, are usually an indication of a problem that the application cannot easily recover from by itself.
There's a little-known fact about checked/unchecked exceptions: The distinction exists only at compile time.
If, by some ugly trick, you manage to throw a checked exception at a place where it isn't declared to be thrown, then it will be handled just like an unchecked exception (i.e. it will will fall through as many stack frames as necessary to reach the nearest matching catch block). And yes, such tricks exist.
And if by default handle your mean the Thread default uncaught exception handler (or the per-thread uncaught exception handler), then yes: they will handle both checked and unchecked exceptions that are not handled by catching them "normally".