Wrinng a RuntimeException - java

Suppose I want to have an unchecked exception for a specific "case" in my code--
say when a queue is 75% full. All I need is an Exception saying "queue has reached the 75% threshold".
One-- the most obvious(?) way of doing this is
public class QueueT extends RuntimeException {
QueueT () {
super("queue has reached the 75% threshold");
}
}
All&only use I have for this exception is
try {
// some stuff here
throw new QueueT();
} catch (QueueT e) {
System.out.print("<<"+e+">>");
}
what I'm wondering is-- what exactly i'm gaining by going with the above-- writing an exception--
rather than the below. Recall: i have no other use-- won't be needing those other methods of Throwable or anything else.
try {
// some stuff here
throw new RuntimeException("queue has reached the 75% threshold");
} catch (RuntimeException e) {
System.out.print("<<"+e+">>");
}
From what i see, the only gain i have is the comfort of calling the constructor without bothering a String attribute.
It's even gainful-- i can easily parameterize the threshold that i'll throw the exception on:
// setting the percentage value here
throw new RuntimeException("queue has reached the" + percentage + "% threshold");
Thanks in advance.

Suppose I want to have an unchecked exception for a specific "case" in my code-- say when a queue is 75% full. All I need is an Exception saying "queue has reached the 75% threshold".
This is a poor case for exceptions. Exceptions are not used for business logic; they are used for exceptional conditions. This seems to be an expected scenario and more like a notification than an exception. How would you expect a person who catches this exception to react? Just ignore it? If so, what is the purpose of the exception? Also, using exceptions in this manner is not performant at all since it has to fill in the stack trace, and doing this repeatedly will make your performance very bad.
As to your other question, the benefit of using your own runtime exception versus RuntimeException is that you now have your own exception that is (hopefully) semantically appropriate, which you can throw or handle appropriately. Simply using RuntimeException by itself doesn't really give that much information.

What you gain is that in your first example,
try {
// some stuff here
throw new QueueT();
} catch (RuntimeException e) {
System.out.print("<<"+e+">>");
}
if you replace catch (RuntimeException e) with catch (QueueTe):
try {
// some stuff here
throw new QueueT();
} catch (QueueTe e) {
System.out.print("<<"+e+">>");
}
Here, you can very exactly say what type of error to catch. Otherwise, you may have another part of your code throw a run time exception and your code to deal with a nearly full queue may try to be applied to an exception totally unrelated to the queue. If you only catch the QueueT exception, you can apply code better and more exactly.

The interest of the first call is easy to understand if you change a bit the catch clause :
try {
// some stuff here
throw new QueueT();
} catch (QueueT e) {
System.out.print("<<"+e+">>");
}
So you will only catch instance of QueueT instead of potential others runtimes like null pointer, such kind of exception you would better let propagate to the entry point in order to detect some coding or design issue.
In Fact in the code you wrote first, you won't be able to differentiate the expected full queue case from a real runtime error. You will lost the error information and the program will act as if the queue were full whereas it isn't
A good practice is to never catch the exception super type, neither runtime nor throwable (the worst one).
Another one is to name an exception with the exception suffix : QueueAboutFullException for example.
Another one is not to use programming by exception if the place you catch the exception is about the same than the one where you throw it. Prefer a simple if because it cost much less than the interruption

Related

Why doesn't Java have setMessage in Exception/Throwable classes?

I am not able to understand why Java doesn't allow to change exception message of an exception of type Exception (or its superclass Throwable) once it has been created. It allows to change the stackTrace using setStackTrace but not the message.
The use case I have seems genuine to me and would appreciate some alternative.
Use case
I have a controller service X that calls let's say 10 other dependent services. To make debugging easy, if a dependent service throws some exception we want to surface some identifiers from service X to its upstream to identify the failed request easily. For this we have requestId which we create and set for each dependency.
Now to avoid duplication across all dependent services and simplify code, we can create a common interceptor that allows us to do some work before and after each call. Something like -
// do some work
requestId = getRequestId(); // create or somehow get requestId
dependentService.setRequestId(requestId);
try {
dependentService.call();
}
catch (Exception e) {
e.setMessage(e.getMessage() + ... + requestId);
throw e;
}
//do some work
But Java doesn't allow us to set message. At the same time, we want to preserve the exception and its type (which could be any of the custom types defined by dependent services), so I don't want to do something like throw new Exception(e.getMessage() + ...)
It's not really what it's meant for, but you could attach another exception with addSuppressed:
} catch (Exception e) {
e.addSuppressed(new ExtraInfoException(...));
throw e;
}
where ... contains the extra info you want to include.
The advantage of this over adding to the exception message is that you can define your ExtraInfoException so that it has the info you want in fields, rather than having to parse it back out of the exception message.
With that said, a more idiomatic way to attach more exception info it would be:
} catch (Exception e) {
throw new ExtraInfoException(e, ...);
}
which has exactly the same advantage of allowing you to return structured information, with the additional advantage that you can catch ExtraInfoException directly, rather than catching Exception and then hunting for the extra info reflectively.
Why doesn't Java have setMessage in Exception/Throwable classes?
The answer to your question is that they (the library designers) did not think that changing a message on an exception was a useful thing to do.
To a large degree1, the designers have taken the view that they shouldn't design the APIs to directly support all possible use-cases ... including the obscure ones that almost nobody will encounter. Like your one2.
And in your case, there are other ways to achieve what you are trying to do; see the other answers.
I did a quick search of the Java bugs database to see if someone else had put in an RFE to request a setMessage method for Throwable or Exception. I couldn't find anything. If your requirement was even slightly common, there would probably be an RFE with an explanation of why it was declined.
1 - Obviously, there are exceptions to this, but that is beside the point.
2 - Obviously you would disagree that your use-case is obscure, but that that is also beside the point. The question is why they haven't implemented this, not whether they were wrong. (Asking / debating whether they were wrong is off-topic, because it is a matter of opinion.)
Resetting a message it's some kind of rewriting the history. You have a catch block when you catch exception and handle them. If you need to throw an exception during the handling, it's a different problem and an exception should be different.
} catch (SomeException e) {
// here we have SomeException and we want to handle it.
// if we can't we throw a new one, because we have a problem with handling.
// if the handling problem cause is SomeException we put it at the cause.
throw new AnotherException("with some message", e);
}
And in the stacks trace we will see that we have AnotherException because of SomeException which gives us information about the root of problem.
Just simply throw new instance like this:
try {
...
} catch(Exception ex) {
throw new Exception ("new message", ex);
}

Catching throwable and handling specific exceptions

Ok I know catching throwable is not a good idea:
try {
// Some code
} catch(Throwable e) { // Not cool!
// handle the exception
}
But recently I was reading through an open sourced code and I saw this interesting (at least to me) piece of code:
try {
// Some Code
} catch (Throwable ex){
response = handleException(ex, resource);
}
private handleException(Throwable t, String resource) {
if (t instanceof SQLEXception) {
// Some code
} else if (t instanceof IllegalArgumentException) {
//some code
} //so on and so forth
}
This doesn't seem to be that bad? What is wrong with this approach?
There are various reasons why you should not catch a Throwable. First of all is, that Throwable includes Errors - and there's normally not much an application can do if one of these appears. Also Throwable reduces your chances of finding out, WHAT has happened. All you get is "something bad has happened" - which might be a catastrophe or just a nuisance.
The other aproach is better but of course I still would not catch Throwable, but try to catch more specific Exceptions, if possible at all. Otherwise you are catching everything and then try to sort out which kind of bad thing happened. Your example could be written as...
try {
...
} catch (SQLEXception ex){
response = ... ;
} catch (IllegalArgumentException ex){
response = ...;
}
...which would reduce the amount of if ( ... instanceof ... ) blocks (which are only needed because the author first decided to catch everything in one big bucket). It something actually throws Throwable, then you don't have much choice, of course.
You are right when you say that catching Throwable is not a good idea. However, the code that you present in your question is not catching Throwable in an evil way but let's talk about that later. For now, the code that you present in your question has several advantages :
1. Readability
If you look at the code carefully, you will notice that even though the catch block is catching a Throwable, the handleException method is checking the type of exception thrown and possibly taking different actions based on the exception type.
The code presented in your question is synonymous to saying:
try {
doSomething();
} catch (SQLEXception ex){
response = handleException(resource);
} catch(IllegalArgumentException ex) {
response = handleException(resource);
} catch(Throwable ex) {
response = handleException(resource);
}
Even if you have to catch 10+ exceptions only, this code can easily take up a lot of lines of code and the multi-catch construct is not going to make the code any cleaner. The code that you present in your question is simply delegating the catch to another method to make the actual method that does the work more readable.
2. Reusability
The code for the handleRequest method could easily be modified and placed in a utility class and accessed throughout your application to handle both Exceptions and Errors. You could even extract the method into two private methods; One that handles Exception and one that handles Error and have the handleException method that takes a Throwable further delegate the calls to these methods.
3. Maintainibility
If you decide that you want to change the way you log an SQLExceptions in your application, you have to make this change in a single place rather than visiting every method in every class that throws an SQLException.
So is catching Throwable a bad idea?
The code that you present in your question is not really the same as catching Throwable alone. The following piece of code is a big no-no:
try {
doSomething();
} catch(Throwable e) {
//log, rethrow or take some action
}
You should catch Throwable or Exception as far away in the catch chain as possible.
Last but not the least, remember that the code you present in your question is framework's code and there are certain errors that the framework can still recover from. See When to catch java.lang.Error for a better explanation.
Catching Throwables out of laziness is a bad idea.
This was particularly tempting before try-multi-catch was introduced.
try {
...
} catch (SomeException e) {
//do something
} catch (OtherException e) {
//do the same thing
} ...
Repeating catch blocks is tedious and verbose, so some people decided to just catch Exception or Throwable and be done with it. This is what should be avoided because:
It makes it difficult to follow what you're trying to do.
You may end up catching a lot of stuff you can't deal with.
You deserve bonus punishment if you completely swallow the Throwable in the catch block. (And we've all seen code that does that...:))
But catching Throwables when it is absolutely necessary is fine.
When is it necessary? Very rarely. In framework-style code there are various scenarios (dynamically loading an external class is the most obvious one), in a standalone application a typical example is to attempt to display/log some kind of error message before exiting. (Bearing in mind that the attempt may fail, so you don't want to put anything critical there.)
As a rule of thumb, if there's nothing you can do about an exception/error, you shouldn't catch it at all.
You posted a link to Jongo, which demonstrates one possible use for this technique: re-using error handling code.
Let's say you've got a large block of error handling code that naturally repeats itself in various places in your code - for example Jongo produces standard responses for some standard classes of errors. It may be a good idea to extract that error handling code into a method, so you can re-use it from all the places it's needed.
However, that's not to say that there's nothing wrong with Jongo's code.
Catching Throwable (rather than using multicatch) is still suspicious, as you're likely to catch Errors that you're not really in a position to handle (are you sure you meant to catch ThreadDeath?). In this situation, if you absolutely have to catch Throwable, it'd be better to "catch and release" (i.e, rethrow anything that you didn't mean to catch). Jongo doesn't do this.
There are exactly two valid uses for using a huge net:
If you will handle everything uniformly, like a top-level catch for logging/reporting, possibly followed by an immediate exit.
To reduce duplication, by exporting all the handling into its own method.
Catch the most derived common ancestor there is to avoid extra-work and increase clarity.
DRY is an important design principle.
In both cases, unless you expected that exception and handled it completely, rethrow.
First of all, catching Throwable makes your application rather intransparent. You should be as explicit as possible on catching exceptions to enable good traceability in exceptional cases.
Let's have a look at the method handleException(...) and see some of the problems that occur by this approach:
you catch Throwable but you only handle Exceptions, what happens if an e.g. OutOfMemoryError of type Error is thrown? - I see bad things to happen...
Regarding good object oriented programming using instanceof breaks the Open-Closed-Principle and makes code changes (e.g. adding new exceptions) really messy.
From my point of view, catch-blocks are exactly made for the functionality that are tried to cover in handleExceptions(...), so use them.
Java 7 solves a bit of the tedium that is multi-catching of similar exceptions with similar handling. You definitely should not be doing what the person has done here. Just catch the appropriate exceptions as needed, it may look ugly but then that's what throws is for, pass it to the method that should catch it and you shouldn't be wasting too much code space.
Check out this link for more information.
Just to provide balance - there is one place where I will always catch (Throwable):
public static void main(String args[]) {
try {
new Test().test();
} catch (Throwable t) {
t.printStackTrace(System.err);
}
}
At least something shows somewhere that something went wrong.
You can always catch different type of exceptions and perform some operations based on the type of the exception you got.
Here is an example
try{
//do something that could throw an exception
}catch (ConnectException e) {
//do something related to connection
} catch (InvalidAttributeValueException e) {
// do anything related to invalid attribute exception
} catch (NullPointerException e) {
// do something if a null if obtained
}
catch (Exception e) {
// any other exception that is not handled can be catch here, handle it here
}
finally{
//perform the final operatin like closing the connections etc.
}

Why Catching Throwable or Error is bad? [duplicate]

Is it a bad practice to catch Throwable?
For example something like this:
try {
// Some code
} catch(Throwable e) {
// handle the exception
}
Is this a bad practice or we should be as specific as possible?
You need to be as specific as possible. Otherwise unforeseen bugs might creep away this way.
Besides, Throwable covers Error as well and that's usually no point of return. You don't want to catch/handle that, you want your program to die immediately so that you can fix it properly.
This is a bad idea. In fact, even catching Exception is usually a bad idea. Let's consider an example:
try {
inputNumber = NumberFormat.getInstance().formatNumber( getUserInput() );
} catch(Throwable e) {
inputNumber = 10; //Default, user did not enter valid number
}
Now, let's say that getUserInput() blocks for a while, and another thread stops your thread in the worst possible way ( it calls thread.stop() ). Your catch block will catch a ThreadDeath Error. This is super bad. The behavior of your code after catching that Exception is largely undefined.
A similar problem occurs with catching Exception. Maybe getUserInput() failed because of an InterruptException, or a permission denied exception while trying to log the results, or all sorts of other failures. You have no idea what went wrong, as because of that, you also have no idea how to fix the problem.
You have three better options:
1 -- Catch exactly the Exception(s) you know how to handle:
try {
inputNumber = NumberFormat.getInstance().formatNumber( getUserInput() );
} catch(ParseException e) {
inputNumber = 10; //Default, user did not enter valid number
}
2 -- Rethrow any exception you run into and don't know how to handle:
try {
doSomethingMysterious();
} catch(Exception e) {
log.error("Oh man, something bad and mysterious happened",e);
throw e;
}
3 -- Use a finally block so you don't have to remember to rethrow:
Resources r = null;
try {
r = allocateSomeResources();
doSomething(r);
} finally {
if(r!=null) cleanUpResources(r);
}
Also be aware that when you catch Throwable, you can also catch InterruptedException which requires a special treatment. See Dealing with InterruptedException for more details.
If you only want to catch unchecked exceptions, you might also consider this pattern
try {
...
} catch (RuntimeException exception) {
//do something
} catch (Error error) {
//do something
}
This way, when you modify your code and add a method call that can throw a checked exception, the compiler will remind you of that and then you can decide what to do for this case.
straight from the javadoc of the Error class (which recommends not to catch these):
* An <code>Error</code> is a subclass of <code>Throwable</code>
* that indicates serious problems that a reasonable application
* should not try to catch. Most such errors are abnormal conditions.
* The <code>ThreadDeath</code> error, though a "normal" condition,
* is also a subclass of <code>Error</code> because most applications
* should not try to catch it.
* A method is not required to declare in its <code>throws</code>
* clause any subclasses of <code>Error</code> that might be thrown
* during the execution of the method but not caught, since these
* errors are abnormal conditions that should never occur.
*
* #author Frank Yellin
* #version %I%, %G%
* #see java.lang.ThreadDeath
* #since JDK1.0
It's not a bad practice if you absolutely cannot have an exception bubble out of a method.
It's a bad practice if you really can't handle the exception. Better to add "throws" to the method signature than just catch and re-throw or, worse, wrap it in a RuntimeException and re-throw.
Catching Throwable is sometimes necessary if you are using libraries that throw Errors over-enthusiastically, otherwise your library may kill your application.
However, it would be best under these circumstances to specify only the specific errors thrown by the library, rather than all Throwables.
The question is a bit vague; are you asking "is it OK to catch Throwable", or "is it OK to catch a Throwable and not do anything"? Many people here answered the latter, but that's a side issue; 99% of the time you should not "consume" or discard the exception, whether you are catching Throwable or IOException or whatever.
If you propagate the exception, the answer (like the answer to so many questions) is "it depends". It depends on what you're doing with the exception—why you're catching it.
A good example of why you would want to catch Throwable is to provide some sort of cleanup if there is any error. For example in JDBC, if an error occurs during a transaction, you would want to roll back the transaction:
try {
…
} catch(final Throwable throwable) {
connection.rollback();
throw throwable;
}
Note that the exception is not discarded, but propagated.
But as a general policy, catching Throwable because you don't have a reason and are too lazy to see which specific exceptions are being thrown is poor form and a bad idea.
Throwable is the base class for all classes than can be thrown (not only exceptions). There is little you can do if you catch an OutOfMemoryError or KernelError (see When to catch java.lang.Error?)
catching Exceptions should be enough.
it depends on your logic or to be more specific to your options / possibilities. If there is any specific exception that you can possibly react on in a meaningful way, you could catch it first and do so.
If there isn't and you're sure you will do the same thing for all exceptions and errors (for example exit with an error-message), than it is not problem to catch the throwable.
Usually the first case holds and you wouldn't catch the throwable. But there still are plenty of cases where catching it works fine.
Although it is described as a very bad practice, you may sometimes find rare cases that it not only useful but also mandatory. Here are two examples.
In a web application where you must show a meaning full error page to user.
This code make sure this happens as it is a big try/catch around all your request handelers ( servlets, struts actions, or any controller ....)
try{
//run the code which handles user request.
}catch(Throwable ex){
LOG.error("Exception was thrown: {}", ex);
//redirect request to a error page.
}
}
As another example, consider you have a service class which serves fund transfer business. This method returns a TransferReceipt if transfer is done or NULL if it couldn't.
String FoundtransferService.doTransfer( fundtransferVO);
Now imaging you get a List of fund transfers from user and you must use above service to do them all.
for(FundTransferVO fundTransferVO : fundTransferVOList){
FoundtransferService.doTransfer( foundtransferVO);
}
But what will happen if any exception happens? You should not stop, as one transfer may have been success and one may not, you should keep go on through all user List, and show the result to each transfer. So you end up with this code.
for(FundTransferVO fundTransferVO : fundTransferVOList){
FoundtransferService.doTransfer( foundtransferVO);
}catch(Throwable ex){
LOG.error("The transfer for {} failed due the error {}", foundtransferVO, ex);
}
}
You can browse lots of open source projects to see that the throwable is really cached and handled. For example here is a search of tomcat,struts2 and primefaces:
https://github.com/apache/tomcat/search?utf8=%E2%9C%93&q=catch%28Throwable
https://github.com/apache/struts/search?utf8=%E2%9C%93&q=catch%28Throwable
https://github.com/primefaces/primefaces/search?utf8=%E2%9C%93&q=catch%28Throwable
Generally speaking you want to avoid catching Errors but I can think of (at least) two specific cases where it's appropriate to do so:
You want to shut down the application in response to errors, especially AssertionError which is otherwise harmless.
Are you implementing a thread-pooling mechanism similar to ExecutorService.submit() that requires you to forward exceptions back to the user so they can handle it.
Throwable is the superclass of all the errors and excetions.
If you use Throwable in a catch clause, it will not only catch all exceptions, it will also catch all errors. Errors are thrown by the JVM to indicate serious problems that are not intended to be handled by an application. Typical examples for that are the OutOfMemoryError or the StackOverflowError. Both are caused by situations that are outside of the control of the application and can’t be handled. So you shouldn't catch Throwables unless your are pretty confident that it will only be an exception reside inside Throwable.
If we use throwable, then it covers Error as well and that's it.
Example.
public class ExceptionTest {
/**
* #param args
*/
public static void m1() {
int i = 10;
int j = 0;
try {
int k = i / j;
System.out.println(k);
} catch (Throwable th) {
th.printStackTrace();
}
}
public static void main(String[] args) {
m1();
}
}
Output:
java.lang.ArithmeticException: / by zero
at com.infy.test.ExceptionTest.m1(ExceptionTest.java:12)
at com.infy.test.ExceptionTest.main(ExceptionTest.java:25)
A more differentiated answer would be: it depends.
The difference between an Exception and an Error is that an Exception is a state that has to be expected, while an Error is an unexpected state, which is usually fatal. Errors usually cannot be recovered from and require resetting major parts of the program or even the whole JVM.
Catching Exceptions is something you should always do to handle states that are likely to happen, which is why it is enforced by the JVM. I.E. opening a file can cause a FileNotFoundException, calling a web resource can result in a TimeoutException, and so on. Your code needs to be prepared to handle those situations as they can commonly occur. How you handle those is up to you, there is no need to recover from everything, but your application should not boot back to desktop just because a web-server took a little longer to answer.
Catching Errors is something you should do only if it is really necessary. Generally you cannot recover from Errors and should not try to, unless you have a good reason to. Reasons to catch Errors are to close critical resources that would otherwise be left open, or if you i.E. have a server that runs plugins, which can then stop or restart the plugin that caused the error. Other reasons are to log additional information that might help to debug that error later, in which case you of course should rethrow it to make sure the application terminates properly.
Rule of thumb: Unless you have an important reason to catch Errors, don't.
Therefore use catch (Throwable t) only in such really important situation, otherwise stick to catch (Exception e)

How can I handle user defined exceptions and after handling them resume the flow of program

/**
* An exception thrown when an illegal side pit was
* specified (i.e. not in the range 1-6) for a move
*/
public class IllegalSidePitNumException extends RuntimeException
{
/**
* Exception constructor.
* #param sidePitNum the illegal side pit that was selected.
*/
public IllegalSidePitNumException(int sidePitNum)
{
super("No such side pit number: "+sidePitNum);
}
}
How do I use this in a program and then resume for there? I do not want the program to end but want to handle the exception and continue.
You need to use try/catch. You can learn a lot about exception handling from Sun's (Oracle's) exception handling tutorials. In that tutorial look at the sections about Catching and Handling that specific address your question.
For example, in the code that calls the method that may throw this exception:
try {
...call method here...
} catch (IllegalSidePitNumException e) {
// Display message (per your comment to BalusC)
System.err.println(e.getMessage());
e.printStackTrace(System.err);
// You can also handle the exception other ways (but do not ignore it)
// Such as correcting some offending values, setting up for a retry
// logging the information, throwing a different exception
}
...program continues executing here...
Just catch it.
try {
doStuffWhichPossiblyThrowsThisException();
} catch (IllegalSidePitNumException e) {
// Don't rethrow it. I would however log it.
}
continueWithOtherStuff();
Sidenote: If this is an "expected" exception, you might want to inherit it from Exception instead of RuntimeException. RuntimeExceptions are intended to be used when something unexpected happens, for example illegal input due to a programmer error.
Of course, you don't give the context where you intend to use the exception so this is all theory (but you do mention that you want to continue the execution).
As others have said, you can do the following:
try {
doSomething();
} catch (SomeException ex) {
doRecovery();
}
doSomethingElse();
But there is no way to do something like the following in Java:
doSomething();
throw new SomeException(...);
doSomethingElse(); // ... after some handler has "resumed" the exception.
The above is a (hypothetical) example of "resumption model" exception handling, and Java does not support this. (Nor does C#, C++ or any other currently popular programming language ... though a couple of historical languages did support it.) In fact, the Java compiler will give you a compilation error for the above, saying that the statements after the throw are unreachable.

Java coding practice, runtime exceptions and this scenario

In the following scenario, I was trying to see how to handle this code and it how it relates to Runtimexception. I have read that is generally better to throw runtime exceptions as opposed to rely on static exceptions. And maybe even better to catch a static checked exception and throw an unchecked exception.
Are there any scenarios where it is OK to catch a static exception, possibly the catch-all Exception and just handle the exception. Possibly log an error message and continue on.
In the code below, in the execute1 method and execute2 method, let us say there is volatile code, do you catch the static exception and then rethrow? Or possibly if there are other errors:
if (null == someObj) { throw new RuntimeException(); }
Is this an approach you use?
Pseudo Code:
public class SomeWorkerObject {
private String field1 = "";
private String field2 = "";
public setField1() { }
public setField2() { }
// Do I throw runtime exception here?
public execute1() {
try {
// Do something with field 1
// Do something with field 2
} catch(SomeException) {
throw new RuntimeException();
}
}
// Do I throw runtime exception here?
public execute2() {
try {
// Do something with field 1
// Do something with field 2
} catch(SomeException) {
throw new RuntimeException();
}
}
}
public class TheWeb {
public void processWebRequest() {
SomeWorkerObject obj = new SomeWorkerObject();
obj.setField1("something");
obj.setField2("something");
obj.execute1();
obj.execute2();
// Possibility that runtime exception thrown?
doSomethingWith(obj);
}
}
I have a couple of problems with this code. There are times when I don't want a runtimeexception to be thrown because then execution stops in the calling method. It seems if I trap the errors in the method, maybe I can continue. But I will know if I can continue later on the program.
In the example above, what if obj.execute1() throws a Runtimeexception, then the code exits?
Edited: This guy seems to answer a lot of my questions, but I still want to hear your opinions.
http://misko.hevery.com/2009/09/16/checked-exceptions-i-love-you-but-you-have-to-go/
"Checked exceptions force me to write catch blocks which are meaningless: more code, harder to read, and higher chance that I will mess up the rethrow logic and eat the exception."
When catching an exception and throwing RuntimeException instead, it is important to set the original exception as a cause for the RuntimeException. i.e.
throw new RuntimeException(originalException).
Otherwise you will not know what was the problem in the first place.
Rethrowing checked exceptions as unchecked exceptions should only be done if you are sure that the checked exception is not to be expected.
Here's a typical example:
try {
hash = MessageDigest.getInstance("MD5").digest(string.getBytes("UTF-8"));
} catch (NoSuchAlgorithmException e) {
// Unexpected exception. "MD5" is just hardcoded and supported.
throw new RuntimeException("MD5 should be supported?", e);
} catch (UnsupportedEncodingException e) {
// Unexpected exception. "UTF-8" is just hardcoded and supported.
throw new RuntimeException("UTF-8 should be supported?", e);
}
There are times when I don't want a
runtimeexception to be thrown because
then execution stops in the calling
method. It seems if I trap the errors
in the method, maybe I can continue.
But I will know if I can continue
later on the program.
You have the right idea. The advice about throwing RuntimeException is that it doesn't require the caller to use a try-block or a 'throws' clause.
If your code can recover from an exception than it really should catch it and not throw anything.
One of the first rules about exceptions is to not abuse them to pass state in your application. They should be used for exceptional situations, not as alternative return values.
The second rule is to catch exceptions at the level you process them. Catch and rethrow does not add much. Any cleanup code in your method should be done in a finally block.
In my opinion catching checked exceptions and rethrowing them as runtime exceptions is abusing the system. It feels like working around the "limitations" of design by contract instead of using those "limitations" to get a more robust application.
Whether or not to handle an exception or simply rethrow it depends on your use case.
For example, if you're reading a file to load data into your application, and some IO error occurs, you're unlikely to recover from the error, so rethrowing the error to the top and consequently terminating the application isn't a bad course of action.
Conversely, if you're anticipating recoverable errors then you should absolutely catch and handle the errors. For example, you may have users entering data in a form. If they enter data incorrectly, your input processing code may throw an exception (e.g. NumberFormatException when parsing a malformed number string). Your code should catch these exceptions and return an error the user, prompting for correct input.
On an additional note, it's probably bad form to wrap all your exceptions with RuntimeException. If your code is going to be reused somewhere else, it is very helpful to have checked exceptions to signify that your code can fail in certain ways.
For example, assume your code is to parse configuration data from a file. Obviously, an IO error may occur, so you will have to catch an IOException somewhere in your code. You probably won't be able to do anything about the error, so you will have to rethrow it. However, someone calling into your code may well be able to handle such an error, for example by backing off to configuration defaults if the configuration can't be loaded from the file. By marking your API with checked exceptions, someone using your code can clearly see where an error may occur, and can thus write the error handling code at the appropriate place. If instead you simply throw a RuntimeException, the developer using your code won't be aware of possible errors until they creep up during testing.

Categories

Resources