Java - Difference between throwing an Exception and catching and rethrowing Exception - java

I'm confused as to what the beneift would be in catching and rethrowing an exception versus just throwing it in the first place.
For example
private void testMethod() throws Exception
{
//some bad code here
}
versus:
private void testMethod() throws Exception
{
try
{
//some bad code here
}
catch (Exception e)
{
throw e;
}
} //end testMethod()
Is this to preserve the stack trace of the error message? I tried setting up an example, but didn't see any different output between the two.
Thanks for the help.

There is no difference in behaviour between your two code samples. (In particular, stacktraces are recorded when an exception is created, not when it is thrown, so a rethrown exception will still have the original stack trace). Usually, people therefore use the simpler idiom.
That is not to say rethrowing doesn't have its uses. For instance, if you wanted to handle all exceptions except FooBarExceptions, you could write:
try {
// bad code
} catch (FooBarException e) {
throw e;
} catch (Exception e) {
e.printStackTrace();
}
Or if the decision to handle an exception is more involved than simply checking its type, you can simply catch it, and rethrow if it turns out you can't handle it:
for (int attempts = 0; attemps < 6; attempts++) {
try {
return crankyMethod();
} catch (Exception e) {
if (fatal(e)) {
throw e;
} else {
// try again
continue;
}
}
}
It is worth noting that when people say rethrow, some mean to throw a different exception, as in the following example:
for (int i = 0; i < array.length; i++) {
try {
process(array[i]);
} catch (Exception e) {
throw new RuntimeException("Could not process element at index " + i, e);
}
}
The advantage of this pattern is to decorate the original exception with additional information that might be relevant (in the above example: what data could not be processed). Note that the original exception is passed to the constructor of the new one, so its stack trace is not lost.

As others have said, in your example there is no difference, and the 2nd form should be avoided.
The only place where it sometimes makes sense is where you need to catch some exceptions, and let others get thrown upwards. Because Java's exception handling syntax is limited, sometime you might do this:
try {
somePieceOfCode();
} catch( RuntimeException e ) {
throw e;
} catch( Exception e ) {
handleException(e);
}
This is sometimes done if somePieceOfCode throws a number of different checked exceptions that don't have a common base class (other than Exception) but need to be handled in the same way. You might not want to just catch Exception because that would also catch things like NullPointerException, and you might prefer for those exceptions to bubble up as-is.
This code will let all RuntimeExceptions bubble upwards, but handle all other exceptions.
This idiom is little unusual, and not everyone likes it, but you might see it in some places.

With this approach you are able to modify the Exception. For example you could give it a more specific message.
With this said, you should generally don't use this technique because
It clusters up your code for no additional benefit (under normal circumstances)
You should only use try-catch blocks where actually necessary because it can slow down execution

The standard reasons to catch and rethrow an exception are:
To log the incident and the exception.
To do some cleanup due to the exception (but often better done in a finally block).
To wrap the exception in a more appropriate exception (I.e. it is probably more appropriate for your processAccount() method to throw an AccountException (or some such) instead of a DbException).

There is no difference. Unless you want to do something with it (the exception) before re-throwing it.

I don't think there is much of a difference, but for what it's worth I'd prefer the first one.
You should not catch an exception unless you can do something about it OR if your class is a boundary beyond which no exception should propagate (e.g. a web controller that catches all exceptions and routers users to friendly error pages).
Simply catching and rethrowing is a waste of keystrokes. It adds no information and does nothing constructive.
The one exception would be to catch a checked exception and wrapping it as an unchecked exception. Otherwise avoid the second idiom.

One of the main benefits of catching then rethrowing is to wrap an exception in another, domain specific exception, so the calling code does not have to worry about implementation specific issues, and can just catch a library specific exception.
There is no real benefit in the example you have given, however a good example of such a benefit can be seen in other libraries - as an example we can look at Hibernate.
Hibernate catches the generic SQLException, and then examines the object to determine the real cause of the exception, before wrapping it in a Hibernate specific exception which is more descriptive of what the issue was in the first place.
However, if you are just catching an exception and throwing the same exception, then you are most likely to do it so you can log the exception in the first place (although this isn't necessarily the best approach to use).

Related

Java catch exception design and performance

I want to understand something about catching exceptions.
If I don't want my application to crash while an exception occurs and have no idea what exception will be thrown, then my way of handling the exception in the code is something like this:
public static void main(String[] args) {
try {
// all my code to new StarGAte with a lot of threads and classes
} catch (Exception e){
//Something went wrong (kill the dev!)
}
}
are there any performance issue in my code with try/catch block?
Is there a better way to handle exceptions?
are they any performance issue with cover all my code with try/catch?
No. If no exceptions are thrown, the exception handling code is never run.
there is a better way to do design exception handling?
Don't catch Exception unless a method you call actually throws Exception. Catch specific checked exceptions, and RuntimeException if you want to be sure.
Exceptions should only be used for error handling. As such they should be rarely executed in your code and their performance will be acceptable most of the time.
Here are some tips on handling exceptions taken from my post Exceptions Guidelines
Don’t catch top-level exceptions
Don’t catch the top-level exception classes such as Throwable, Exception or RuntimeException directly in your API, unless you really know you need to and you are at the very top of your code base (your main method and top level server/daemon code). These exception classes contain many unrecoverable exceptions that can’t be handled safely. This is especially true for the Throwable class which also catches Error exceptions that the JVM might throw such as out of memory exceptions. Catching these exceptions and continuing to run your application may result in data corruption and undefined behavior.
Make sure that your catch() statements are ordered correctly from most specific to most general. You can use multi-catch statements to group exceptions that need the same treatment like logging an error:
catch( Exception1 | Exception2 | Exception3 e) {
logger.log( "Bad Exception: " + e.getMessage(), e );
}
Use the common parent if multiple exceptions can be thrown and handled the same way. For example catching IOException will catch automatically FileNotFoundException because it inherits form IOException.
Avoid catching the Throwable class! Bad things will happen when you start catching unrecoverable JVM exceptions.
Don’t use exceptions for flow-control
It slows down your code and makes it less maintainable. It is considered very bad practice.

when throw new Error() is written in try block why catch block is not executed .it go in finally only .Latter code also not executed

Example bellow a program ,where in try block defectedCode() method is called ,So why only output shown only C with "Exception in thread "main" java.lang.Error".
public class ExceptionTest {
public static void defectedCode(){
throw new Error();
}
public static void main(String args[]){
try{
defectedCode();
System.out.println("A");
}catch(Exception e){
System.out.println("B");
}finally{
System.out.println("C");
}
System.out.print("D");
}
}
Exception in thread "main" java.lang.Error
C
at ExceptionTest.defectedCode(ExceptionTest.java:15)
at ExceptionTest.main(ExceptionTest.java:21)
Java Result: 1
The main reason for this is that you throw an Error but you catch an Exception.
If you look at the Throwable hierarchy the point is clear. You can't catch an Error with an Exception. Hence the catch block isn't entered and finally will be called.
Try this:
try{
defectedCode();
System.out.println("A");
}catch(Throwable e){
System.out.println("B");
}finally{
System.out.println("C");
}
You're not supposed to catch errors
An Error "indicates serious problems that a reasonable application should not try to catch."
while
An Exception "indicates conditions that a reasonable application might want to catch."
Talking about your code, you're throwing an error and catching an exception, it must be evident by now that they are 2 discrete entities
Error along with RuntimeException & their subclasses are unchecked exceptions. All other Exception classes are checked exceptions.
Checked exceptions are generally those from which a program can recover & it might be a good idea to recover from such exceptions programmatically. Examples include FileNotFoundException, ParseException, etc. A programmer is expected to check for these exceptions by using the try-catch block or throw it back to the caller
On the other hand we have unchecked exceptions. These are those exceptions that might not happen if everything is in order, but they do occur. Examples include ArrayIndexOutOfBoundException, ClassCastException, etc. Many applications will use try-catch or throws clause for RuntimeExceptions & their subclasses but from the language perspective it is not required to do so. Do note that recovery from a RuntimeException is generally possible but the guys who designed the class/exception deemed it unnecessary for the end programmer to check for such exceptions.
Errors are also unchecked exception & the programmer is not required to do anything with these. In fact it is a bad idea to use a try-catch clause for Errors. Most often, recovery from an Error is not possible & the program should be allowed to terminate. Examples include OutOfMemoryError, StackOverflowError, etc.
Do note that although Errors are unchecked exceptions, we shouldn't try to deal with them, but it is ok to deal with RuntimeExceptions(also unchecked exceptions) in code. Checked exceptions should be handled by the code.
Because Error is not Exception, so the catch block is not monitoring it
use throw new Exception()
An Error is not an Exception.
The base class for throwable objects is Throwable.
Errors and exceptions are two different types of throwables. However, errors are usually not supposed to be caught, which is why people use catch(Exception e) to catch basically all exceptions that they should catch.
Obviously, since Error is not a subclass of Exception, it's not affected by catch(Exception e), so it's not caught. finally is always executed, regardless of whether the throwable has been caught or not.
Though ethically you should not catch an error, you can still catch that as a Throwable Object.

How can I get a method to throw a custom exception I've created?

So my custom exception is PatternFormatException, and I've appended throws PatternFormatException, to the end of my method, but I'm wondering how I can actually get the method to physically throw it? Do I use if statements? i.e.
if //[doesn't_parse] throw PatternFormatException
This seems cumbersome for many different lines of code? Can I catch a more universal in built exception i.e. NumberFormatException, and then in the handling of this, throw my own exception?
You throw an exception using the throw keyword:
throw new PatternFormatException(...);
Generally you want to catch exceptions as early as they occur and handle them properly. If you want your parser (or whatever program you are writing) to generate meaningful errors, it's usually a good idea to wrap any caught exception and re-throw it, embedded in a more meaningful exception, giving the user a better idea of how things went wrong.
Something like this:
try {
doSomething(); // throws SomeException
doSomethingElse(); // throws SomeOtherException
}
catch (Exception e) {
throw new PatternFormatException(..., e);
}
generally is fine, if you know exactly what exceptions might happen and if all of them are properly encapsulated by PatternFormatException. However, the key idea of Exceptions in Java is that you are always aware of all the possible Exceptions that can happen. That is why Java forces you to add all possibly thrown Exceptions (except for RuntimeException) to the method declaration.
A safer design would be:
try {
doSomething(); // throws SomeException
doSomethingElse(); // throws SomeOtherException
}
catch (SomeException e) {
throw new PatternFormatException(..., e);
}
catch (SomeOtherException e2) {
throw new PatternFormatException(..., e2);
}
catch (Exception e3) {
throw new UnexpectedPatternFormatException(..., e3);
}
Note that the first two catches call different constructors, and thus can handle different Exceptions differently. The last catch wraps an unexpected exception because your program encountered an exception (probably a RuntimeException) that you did not plan for. If users then complain about UnexpectedPatternFormatException, you can just go back to your code and fix the code so that the underlying Exception either does not get thrown anymore or gets wrapped in a more meaningful way. You can also just use a single UnexpectedMySomethingException class as the fall-back for all try/catch blocks that you have, to keep things a bit simpler.
One last word should be said about issues caused by Exceptions: Even though, Java uses Exceptions for all kinds of situations, even those that are largely not in the control of the Java programmer (e.g. when accessing files or even trying to parse strings as numbers), always be aware that throwing and catching Exceptions is actually quite expensive, which is why many people tend to avoid that. Only really use Exceptions, if performance is not of an issue (when the Exception is a rare event).
Also, Exceptions can threaten the integrity of your program's state if you throw an Exception and catch it too late, so that lines that should have been executed did not get executed (e.g. code for cleaning up resources or other code that is needed to keep the program state "correct"), and, as a result, the only safe thing to do is to shut down the program.
If I understand your question correctly you could just do this:
If(somethingBad){
throw new PatternFormatException();
}
As stated in a response below. If your going to check this exception over and over again you might want some Static Method/Class Method (use your programming brain). For example you could do something like:
void checkForException(String pattern, String check){
If(!check.equals(pattern)){
throw new PatternFormatException();
}
}
Now all you have to do is:
try{
checkForException("abc","123");
}catch(PatternFormatException pfe){
System.out.println(pfe); //Whatever you want to happen if the exception is thrown
}
Remember though, ONLY use exceptions for exceptional situations...
Have a read over this for more information on exceptions. I find that I next to never use exceptions.

What is the good practice to terminate program in catch clause

I have a method throws an Exception
public int myMethod throws Exception
I have another function calls myMethod function and hava try-catch block.
I throws a runtime exception to enforce the program to be terminated.
Is this a proper way to terminate the program? If I do this way, it prints the stack trace twice and the stack trace from RuntimeException is useless.
What is the suggested way to terminate program in catch clause with printing the full stack trace.
public int callMyMethod(){
try{
myMethod();
}
catch(Exception ex){
ex.printStackTrace(System.out);
throw new RuntimeException();
}
}
The answer is "it depends".
If this code is part of the application itself then calling System.exit(int) is possibly the best option. (But if the application is "failing", then you should call exit with a non-zero return code. Zero conventionally means "succeeded".)
However, if there is a significant possibility that this code is going to be embedded / reused in a larger Java application, calling System.exit(...) is problematic. For instance a library that calls System.exit(...) when something bad happens is going to cause havoc for an application that uses it.
For something like that, you might throw a custom runtime exception which you catch and handle specifically in your main method. (If I was doing that, I'd pass the Exception as a constructor parameter to the custom exception ... and make it the cause exception. And I wouldn't print it / log it at that point.)
(Calling System.exit(...) also causes problems when you are unit testing ... 'cos the call will most likely pull the plug on the JVM running the test suite!)
The other point is that catch (Exception ...) is almost always a BAD IDEA. The point is that this catches just about everything (including all sorts of things that you never dreamed could happen!) and buries them. It is far better to catch the specific exceptions you are expecting (e.g. checked exceptions) and can deal with ... and just let the rest propagate in the normal way.
If you are stuck with catch (Exception ...) because you are using something that is declared as throwing Exception, the best way to deal with it is to change the throws Exception. And the sooner the better. Change the throws Exception to declare a list of (more) specific exceptions that you expect to be thrown by the method.
public int callMyMethod(){
try{
myMethod();
}
catch(Exception ex){
ex.printStackTrace(System.out);
System.exit(0); // terminates with exit code 0, no extra stack trace.
}
}
Exception handling is one of the most important aspects in programming.
The answer for your question depends on what type of application you are working on.
system.exit(0) will just terminate your program and this can create a lot of havoc .
Also make sure that you never catch Exception , if you are doing that then you are catching all the types of exceptions which you may not intend to handle also.
Always catch Specific exception such that it gives you opportunity to handle it in a manner which you need.

Java Global Exception Handler

I have a question regarding the exception handler.
I have a structured code for my project which has many packages and classes for different purposes.
In this code, there are many places where I try to catch different types of exceptions.
To mention a few of them are SAXException, IOException, NumberFormatException, ParserConfigurationException, RuntimeException and so on.
In all the cases where I catch the exceptions, I only print a stack trace. The moment I come across an exception, I will figure out from the stack trace the function where it occurred and fix it accordingly. I don't do anything else with the exception, neither I intend to do, since the code size is not huge and fairly easy to debug for me.
Now, I am using an external java library which is provided by a third-party developer. This library throws exception for every possible function that I call. I am trying to write a wrapper over this library in order to utilise it. However, I find try/catch blocks everywhere in my code, due to this library.
For example my code looks like this -
Class Wrapper
{
public void method1()
{
....
try
{
...
third party library calls...
...
} catch (Exception e) { e.printStackTrace(); }
}
public void method2()
{
....
try
{
...
third party library calls...
...
} catch (Exception e) { e.printStackTrace(); }
}
// ... and so on... there are 50-100 methods like this.
// some are even one-liners.
}
Given this scenario, should I switch to Global Exception handler as mentioned in this discussion?
Will this avoid write try/catch blocks everywhere in my code?
Also, should I remove the existing try/catch blocks?
Thanks!
If you do not want your client code to handle checked exceptions, you can do something like following in your wrapper.
public void method1() {
try {
//3rd party code here....
}
catch(RuntimeException e){
throw e;
}
catch(Exception e){
throw new RuntimeException(e.getMessage(),e);
}
}
Notice, this avoids swallowing the exceptions thrown by 3rd party library and does not force clients to handle Checked exceptions like IOException, SQLException etc.
If you don't mind your program exiting after any exception, you can probably use a global exception handler. You may have to put throws Exception (or a more specific exception class) at a whole bunch of places (to prevent unhandled-exception compile-time errors), which is very far from ideal (and could end up with less "pretty" code than catching exception where they are thrown).
If, on the other hand, you want your program to recover from errors (which is generally wanted in production-level code), you'll need appropriately placed try-catch statements (which could involve having try-catch statements everywhere in your code).
As example, if you get an IOException, you may want to retry, or if you get a NumberFormatException, you may want to notify the user that the input was invalid and let him/her try again.
You should not just remove try-catch statement, you should look at what they do, whether this behaviour is what you want and whether it will be reproducible with alternative solutions (e.g. a global try-catch statement).

Categories

Resources