I’m consuming an external SOAP service in my Spring app. The SOAP service can throw an Exception while connecting so I catch that in a try catch block:
try {
response = soapService.callService(request);
} catch (Exception e){
throw SoapServiceException("explaining",e);
}
if (BAD_STATUS_CODE.equals(response.getStatusCode()) {
throw CustomException("explaining", e);
}
return response;
As you can notice, I also want to throw an exception when response is not what caller would expect, maybe for example because valid request format but values not found in soap service.
Is this a good practice? I'm trying to prevent wrapping the response object in another object that keep the error codes. I think it would be nice if service caller handles the exceptional cases like soap exception or the response exception. Thanks for your advice.
Exception are a feature of the java programming language but are not mandatory to be used. Well you may have to catch the existing ones, but you don't have to raise new one.
This is a design decision for your application/framework/library. It is much better if the way to handle error in general is consistant accross the whole codebase. There isn't a better, universal way. It is a collective choice and also depend of the general expected behavior of your program.
A simple design
A "naive" or at least simple implementation typically would raise exception for many unsupported cases as this is an easy way to interrupt the execution, get a log of the error and an easy way to investigate.
In that way of seeing things, it isn't necessarily worth to have checked exception. Your exceptions can derive from RuntimeException, you don't need to declare them and simply raise them when there an issue.
The drawback of such design is that developpers will likely raise exception in many cases and that most these "exceptional" cases are actually common case in your application. A file is not found ? Well that's common. The network isn't available ? That's to be expected. The service didn't return what you do expect ? That can happen more often than you think...
At least in our production where we have thing like thousand of machines and hundred thousand of TPS everything will happen.
Toward a more robust implementation
So typically you'll separate what you'll consider to be something that you expect to happen and have to deal with (like a timeout for a network request or the DB being temporarilly unvalaible) or what shall never happen (a file part of your artifact distribution missing) or invalid parameters provided to a function (a code bug).
You'll keep exception for what is truely exceptionnal, and typically make them RuntimeException/unchecked because there nothing to be done. You just want such bugs to be logged and repported.
For all the rest, there may be exception in the middle but not globally. You want to deal with them and consider them as normal behavior.
In that case, the choice is your depending of the design.
But typically if I have to act and proceed normally when that occurs, I prefer as well to not have an exception. Typically for a network request, I would consider the Time Out to be actually be a valid response and returned as this to be part of the values I model in my business domain.
To have the Error and errors code part of my data domain allow me to accumulate/aggregate errors and to fine tune how I react to them. An exception on the opposite is more an all or nothing.
This allows for more flexibility on how functionnally I choose to react... Like I performed 10 requests, one time out, on returned an error, I don't want exceptions. I want the results and a "merge" strategy that depend of the functional aspects of my application.
In your example of BadStatus, I would consider it as an exception if that 's an error code I get because I provided invalid inputs (a bug in my code). But if that's because there no network or because there was an external failure, that expected behavior for me, so I would not throw.
That's my design choice, that's the teams I have been working with design choice. This doesn't has to be the universal choice. Just be sure you all agree on how to deal with such case and it match your overall software design
Checked exceptions
They force you do deal with it, and this can be a bless or a curse depending of the context.
This is a choice that you have in your design.
Do you only throw exception in exceptional cases that should not happen and use it as bug detection mechanism ? Then I think they are useless and when I use this strategy I wrap them in a derivate of RuntimeException to simplify my code and in a few key areas of my code I have generic catch all mechanisms that can be seen as framework lvl so I ensure I always return a proper response (even if that one with an error) and then I can centralize the loggging.
But again if you think the client shall alway deal with it, use the checked exception. The problem with that is that most often the caller cannot do anything directly, he may need to wrap into many intermediate just to forward it or have an handless list of checked exceptions.
So I am not that fond of them. But again that a design decision for you and the team.
Throwing exceptions in your code when the behaviour is unexpected is absolutely fine. Just be sure to mark your method
void testMethod() throws CustomException, CustomException2, ..
so that the caller of the method knows that there is a chance that an exception can be thrown.
Uncaught exceptions will cause your program to terminate so be sure to catch, and handle appropriately.
[HttpDelete]
[Route("api/employee/delete")]
public void Delete(int Id)
{
using (EmployeeDBEntities db = new EmployeeDBEntities())
{
try
{
Employee emp = db.Employees.FirstOrDefault(e => e.EmpId == Id);
db.Employees.Remove(emp);
db.SaveChanges();
}
catch (Exception ex)
{
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.BadRequest)
{
Content = new StringContent(ex.Message)
});
}
}
}
In all projects that I've been working we used exactlly as you, we throw an exception instead of wrapp this in any response object. Looks good for me.
I would like to ask a code style question around Java Exceptions. I am using Java to call a C/C++ library using JNI. The convention in the library I am using is that most of the methods I can call will throw the same exception type for all errors. Let's call that a LibException. Now LibException is really a wrapper exception for a multitude of errors that can come up ranging from authentication problems, connection problems or more serious problems like corrupt input etc. LibException also contains an error code int as well as the error description string.
Even more confusingly LibException can also wrap one of my own exceptions if I throw it at the library in a callback! What I mean by that is that I sometimes provide a callback method, it is called by the library and I sometimes have to throw an exception in the callback. In that case the library picks up the exception, wraps it up in a LibException and throws it back at me in the original method call.
I would like each of the underlying problem to be handled differently. Authentication problems need to be shown to the user so he can retry, users should be notified of connection problems, but more serious problems may have to trigger my diagnostics report system (an automated mechanism that can send me parts of the logfile for debugging) and of course any exceptions I throw towards the library in the callback need to be rethrown as the original exception type.
Since I am calling different methods at multiple locations, I thought it would be a good idea to put some structure around the exception handling of LibExceptions. This is to avoid code repetition but most importantly to make sure that the different exception types are handled properly and that future me does not forget to, for example, notify the user that authentication failed.
I have tried a bunch of approaches but I am not entirely happy with the code structure I get so I would like some ideas on best practices from the community.
Static method that includes logic to sort the exceptions and throw a bunch of other exceptions
public static void handleException(LibException e) throws AuthenticationException, ConnectionException, SeriousException, MyException (MyException would be my exception that I throw in the callback)
+ve This works well in that it forces the handling of all the thrown exceptions.
+ve If a new exception type is added, the compiler would force me to handle the new exception
-ve Even though handleException() is a method that always throws an exception, the compiler (rightly) does not know this. This means that if we use handleException() in a method that has to return something, the compiler complains that a return type was missed. To make the compiler happy I have to throw another exception right after calling handleException() so the compiler understands that it will not be getting a return value because an exception is definitely thrown.
-ve I don't like the line that looks like Handler.handleException(libEx) since it's not entirely obvious that it throws a bunch of exceptions.
-ve Hard to customize the exception messages with context from the location the exception occurred (i.e. which URL we could not connect to).
A method that returns an enum with the different types of exceptions that I defined. Based on the enum I can then create the different exceptions to throw.
public static ExceptionTypeEnum Handler.
+ve Since I create the exceptions, I can now customize some error messages with extra context
-ve I could still forget to handle an enum (especially if I create a new category in the future)
-ve I still need a bunch of custom code to create the exceptions at every place I catch a LibException
Similar to #2 but instead of an enum return I could have multiple methods such as isAuthenticationException(libEx) or isConnectionProblem(libEx) and then accordingly throw the exceptions myself.
-ve I would definitely forget to handle all sections properly especially if a new exception type is added later.
The exception handler could return an exception to throw up. But since we throw a number of different exceptions the getException() method would have to return the Exception base class. This means that exception handlers would have to have prior knowledge of what exceptions could be thrown and also catch the Exception class making my exception handling more difficult.
Now in case I confused everyone with this question, I guess what I am trying to find an elegant solution to is similar to the problem described on section 'Checked exceptions inappropriately expose the implementation details' on page http://www.ibm.com/developerworks/java/library/j-jtp05254/index.html
Does the community have any other suggestions of a coding method to properly and elegantly handle these LibExceptions?
I have a method which calls several other methods. However these methods and other operations (like navigating array or working with null pointers) can throw runtime exceptions which are not explicit.
One could make use of a try{...}catch(Exception e){...} block to make sure that no wild exception crosses the barrier and my method does not throw any exception which isn't explicit declared in its signature.
However this solution is ugly and prone to bugs since I may not want to catch everything or I may want to provide some specific behavior given a specific error situation.
So, is there a way for Eclipse to show me something like "careful, your method says that it throws IllegalArgumentException and JSONException, but you are missing some runtime exceptions that you can catch internally or declare that you throw them as well"? So far Eclipse only shows me which Exceptions I really must declare in the method's signature, but I also wanna be forced to declare the (Unchecked) runtime exceptions.
Ps.: This is not a duplicate of How can I know what exceptions can be thrown from a method? since the best solution there is to use a catch-all block.
Short answer is: you can't.
That is the nature of RuntimeException; they are not "checked" exceptions; therefore you are not enforced to add them to your throws clause.
The important thing is that on some level your code understands that RuntimeExceptions might occur; and deals with them in the correct way.
Example: assume you are working on "providers" that should process requests that are coming from a restful API.
There are now two types of problems:
A) those that you "expect" and where you give fine granular feedback on. For example your API spec might list many 400.xxx, 409.xxx, ... answers for various problems. It makes sense to use "checked" exceptions for these things (the code throwing an "ApiException" already knows that this error should show up as 409.xxx to the user of the restful API).
B) Then there are those that you "do not expect"; basically those are reflecting "bugs" in your code; like "he, this argument should not be null"; "he, this 'key' is unknown". For those ... just throw RuntimeExceptions. But make sure that your top layer catches them; and for example turns them into a 500.xxx answer to the user ("some internal error happened, here is the stacktrace; send us a bug report)
Your request has an interesting twist. You want to catch all exceptions that the invoked methods may throw, but you don’t want to use catch(Exception ex){ … } because that would imply that … you are catching all exceptions.
Let’s ask the other way round: which exception do you want to exclude from the catch clause? If you want to catch all checked exceptions as well as all runtime exceptions, you exclude Errors and those runtime exception which may not occur. Well, that’s what catch(Exception ex){ … }already does. It doesn’t catch Errors and you don’t need to bother about exceptions that are impossible to occur.
That said, there is a reason why you shouldn’t catch RuntimeExceptions. They are there to signal conditions that normally shouldn’t occur even if their impossibility can’t be proven at compile time.
If you want your IDE to collect all runtime exceptions that are in principle possible, consider
Every access to an object or array may cause a NullPointerException
Every array access may cause an ArrayIndexOutOfBoundsException or NegativeArraySizeException
Every array write access may cause an ArrayStoreException
Every integer division may cause an ArithmeticException
Every runtime type cast, including those hidden by Generics may produce a ClassCastException
etc. And these are only the exceptions associated with language constructs, not containing those possibly produced by library methods.
The set of possible exceptions will soon explode if you really ask a tool to collect them all for a particular piece of code and all invoked methods.
You would need an insanely large list of exception types in your catch clause and that only to hide the fact that you are actually attempting to catch all exceptions (as catch(Exception ex) would immediately make apparent)…
I find that Java's reflection API is exception verbose, and I often want to catch each specific exception, but just throw Exception. Is this poor practice, or do you really throw all of those exceptions on the method signature? Every method that calls that method must then deal with each of those specific exceptions in some way. Instead, I'm thinking of doing this:
public void someMethod()
throws Exception {
try {
// do a bunch of reflection...
} catch(ClassCastException classCastException) {
throw new Exception("Some specific message.", classCastException);
} catch(InvocationTargetException invocationTargetException) {
throw new Exception("Some specific message.", invocationTargetException);
}
}
Is that poor practice?
Rethrowing different kinds of exceptions that a method throws as a single unified exception can sometimes be a reasonable approach.
Using java.lang.Exception specifically for this is a bad idea, because it's too unspecific.
You might rethrow each different exception as some custom MyException or something like that. That's sometimes a reasonable approach when you're not really interested in why someMethod failed.
Short answer
Reflection is verbose by design
Exception translation is idiomatic (catching lower level exception and abstracting it to a higher level)
... but don't overuse!
Prefer custom exceptions to java.lang.Exception; it's probably too high of an abstraction
Point 1: Avoid reflection if at all possible
Here's a quote from Effective Java 2nd Edition, Item 53: Prefer interfaces to reflection:
[The power of reflection], however, comes at a price:
You lose all the benefits of compile time checking, including exception checking.
The code required to perform reflective access is clumsy and verbose. It is tedious to write and difficult to read.
Performance suffers. Reflective method invocation is much slower than normal method invocation.
[...] As a rule, objects should not be accessed reflectively in normal application at runtime. There are a few sophisticated applications that require reflection. Examples include [omitted on purpose]. If you have any doubts to whether your application falls into one of these categories, it probably doesn't.
Point 2: Exception translation can be a good thing, but don't overuse
Here's a quote from Effective Java 2nd Edition, Item 61: Throw exceptions appropriate to the abstraction.
It is disconcerting when a method throws an exception that has no apparent connection to the task that it performs. This often happens when a method propagates an exception thrown by a lower-level abstraction. [...]
To avoid this problem, higher layers should catch lower-level exceptions and, in their place, throw exceptions that can be explained in terms of higher-level abstraction. This idiom is known as exception translation.
[...] While exception translation is superior to mindless propagation of exceptions from lower layers, it should not be overused. Where possible, the best way to deal with exceptions from lower layers is to avoid them, by ensuring that lower-level methods succeed. [...]
If it is impossible to prevent exceptions from lower layers, the next best thing is to have the higher layer silently work around these exceptions, insulating the caller of the higher-level method from lower-level problems. Under these circumstances, it may be appropriate to log the exception using some appropriate logging facility. This allows an administrator to investigate the problem, while insulating client code and end user from it.
Point 3: java.lang.Exception is way too general
Looking at the documentation, one can see a long list of direct known subclasses, with a wide-ranging topics from Reflection, RMI, XML parsing, I/O, GUI, cryptography, etc.
Declaring that a method throws Exception is probably a poor API design decision, because it does not immediately tell the user anything useful about what category the exceptions may be, or under what circumstances they may be thrown. Contrast this with a hypothetical ReflectionException; this is a lot more informative, and it also allows user to catch specifically ReflectionException and not, say, an IOException that somehow slipped through.
Related questions
In Java, is using throws Exception instead of throwing mulitple specific exceptions good practice?
Catching several exceptions and rethrowing a general exception
java.lang.Exception vs. rolling your own exception
When should Throwable be used instead of new Exception?
Need authoritative source for why you shouldn’t throw or catch java.lang.Exception
In Java, when should I create a checked exception, and when should it be a runtime exception?
When to choose checked and unchecked exceptions
The case against checked exceptions
I agree with your approach, except I think throwing Exception is not good, eventually every method declaration in your application will end with "throws Exception". For cases like this, where the exception will only occur if you made an error, it's better to make the wrapping exception an unchecked exception.
If the exception thrown by the method (contained in the InvocationTargetException) have the potential to be interesting to you, you could make it the wrapper a different subclass of unchecked exception or create a specific checked exception subclass for it, but wrap things like the ClassCastException in unchecked exceptions.
To use throws Exception is always a bad idea. In your case you have to consider the following things.
Can I recover from the error at the next imediate level? If so use all the different exceptions for clarity.
Can I recover from the error some levels up? If so use a wrapper exception because it would pollute all methods on the way up with technical details to use the explicit ones.
I can't recover from the error or it happens in a completely different place/many levels above. If wrap each exception into RuntimeException or a custom ReflectionFailedRuntimeException to avoid technical exceptions leaking throughout your application.
Alos, normally you should code it in a way that you can expect the reflection to work in most cases without Exceptions, so it would be also considerable to make it RuntimeException wrapping anyway.
Think of what you want to achieve. The caller of your method is not supposed to know you're using reflection to achieve your goal. That's none of its business. If you would just put all those exceptions in your throws clause that would break that encapsulation.
Catching these exceptions and wrapping them in your own is therefore the way to go. Then you just have to decide which exception to throw. Exception itself is a very bad idea (I'm of the opinion it should even be abstract to suggest that) The type of the exception should be related to the problem.
Throw an exception that relates to what you're trying to do and to why it failed (if it failed because a given argument is inappropriate, IllegalArgumentException would be one). Also make an informed decision on whether you would like to throw a checked or an unchecked exception (RuntimeException).
I would in some cases.
The normal way I would decide is look at what methods calling someMethod() would expect or reasonably be expected to know. So if someMethod() was doing something IO related I'd throw an IOException, if it was related to a library I was writing I might throw a custom exception..
I'd only throw the individual exceptions if the callers of someMethod() would reasonably be expected to know it used reflection for its implementation.
I guess the key question is "If someMethod() didn't use reflection, and something went wrong, what would it do?" That will normally give you the answer.
Thats still an acceptable policy if you are collecting all exceptions and throwing a custom exception of yours.
public void someMethod()
throws MyCustomException {
try {
// do a bunch of reflection...
} catch(ClassCastException classCastException) {
MyCustomException ex1 = new MyCustomException("Some specific message.", classCastException);
// Logic to add more details to exception AND/OR handling current exception.
throw ex1;
} catch(InvocationTargetException invocationTargetException) {
MyCustomException ex1 = new MyCustomException("Some specific message.", classCastException);
// Logic to add more details to exception AND/OR handling current exception.
throw ex1;
}
}
Generally catching exception should be for a reason of handling them in some way. Simply re-throwing an exception of larger scope makes no sense anywhere to me.
This question already has answers here:
Closed 10 years ago.
The community reviewed whether to reopen this question last year and left it closed:
Original close reason(s) were not resolved
Possible Duplicate:
When to choose checked and unchecked exceptions
When should I create a checked exception, and when should I make a runtime exception?
For example, suppose I created the following class:
public class Account {
private float balance;
/* ... constructor, getter, and other fields and methods */
public void transferTo(Account other, float amount) {
if (amount > balance)
throw new NotEnoughBalanceException();
/* ... */
}
}
How should I create my NotEnoughBalanceException? Should it extend Exception or RuntimeException? Or should I just use IllegalArgumentException instead?
There's a LOT of disagreement on this topic. At my last job, we ran into some real issues with Runtime exceptions being forgotten until they showed up in production (on agedwards.com), so we resolved to use checked exceptions exclusively.
At my current job, I find that there are many who are for Runtime exceptions in many or all cases.
Here's what I think: Using CheckedExceptions, I am forced at compile time to at least acknowledge the exception in the caller. With Runtime exceptions, I am not forced to by the compiler, but can write a unit test that makes me deal with it. Since I still believe that the earlier a bug is caught the cheaper it is to fix it, I prefer CheckedExceptions for this reason.
From a philosophical point of view, a method call is a contract to some degree between the caller and the called. Since the compiler enforces the types of parameters that are passed in, it seems symmetrical to let it enforce the types on the way out. That is, return values or exceptions.
My experience tells me that I get higher quality, that is, code that JUST WORKS, when I'm using checked exceptions. Checked exceptions may clutter code, but there are techniques to deal with this. I like to translate exceptions when passing a layer boundary. For example, if I'm passing up from my persistence layer, I would like to convert an SQL exception to a persistence exception, since the next layer up shouldn't care that I'm persisting to a SQL database, but will want to know if something could not be persisted. Another technique I use is to create a simple hierarchy of exceptions. This lets me write cleaner code one layer up, since I can catch the superclass, and only deal with the individual subclasses when it really matters.
In general, I think the advice by Joshua Bloch in Effective Java best summarises the answer to your question: Use checked expections for recoverable conditions and runtime exceptions for programming errors (Item 58 in 2nd edition).
So in this case, if you really want to use exceptions, it should be a checked one. (Unless the documentation of transferTo() made it very clear that the method must not be called without checking for sufficient balance first by using some other Account method - but this would seem a bit awkward.)
But also note Items 59: Avoid unnecessary use of checked exceptions and 57: Use exceptions only for exceptional conditions. As others have pointed out, this case may not warrant an exception at all. Consider returning false (or perhaps a status object with details about what happened) if there is not enough credit.
When to use checked exceptions? Honestly? In my humble opinion... never. I think it's been about 6 years since I last created a checked exception.
You can't force someone to deal with an error. Arguably it makes code worse not better. I can't tell you the number of times I've come across code like this:
try {
...
} catch (IOException e) {
// do nothing
}
Whereas I have countless times written code like this:
try {
...
} catch (IOException e) {
throw new RuntimeExceptione(e);
}
Why? Because a condition (not necessarily IOException; that's just an example) wasn't recoverable but was forced down my throat anyway and I am often forced to make the choice between doing the above and polluting my API just to propagate a checked exception all the way to the top where it's (rightlfully) fatal and will be logged.
There's a reason Spring's DAO helper classes translate the checked SQLException into the unchecked DataAccessException.
If you have things like lack of write permissions to a disk, lack of disk space or other fatal conditions you want to be making as much noise as possible and the way to do this is with... unchecked exceptions (or even Errors).
Additionally, checked exceptions break encapsulation.
This idea that checked exceptions should be used for "recoverable" errors is really pie-in-the-sky wishful thinking.
Checked exceptions in Java were an experiment... a failed experiment. We should just cut our losses, admit we made a mistake and move on. IMHO .Net got it right by only having unchecked exceptions. Then again it had the second-adopter advantage of learning from Java's mistakes.
IMHO, it shouldn't be an exception at all. An exception, in my mind, should be used when exceptional things happen, and not as flow controls.
In your case, it isn't at all an exceptional status that someone tries to transfer more money than the balance allows. I figure these things happen very often in the real world. So you should program against these situations. An exception might be that your if-statement evaluates the balance good, but when the money is actually being subtracted from the account, the balance isn't good anymore, for some strange reason.
An exception might be that, just before calling transferTo(), you checked that the line was open to the bank. But inside the transferTo(), the code notices that the line isn't open any more, although, by all logic, it should be. THAT is an exception. If the line can't be opened, that's not an exception, that's a plausible situation.
IMHO recap: Exceptions == weird black magic.
being-constructive-edit:
So, not to be all too contradictive, the method itself might very well throw an exception. But the use of the method should be controlled: You first check the balance (outside of the transferTo() method), and if the balance is good, only then call transferTo(). If transferTo() notices that the balance, for some odd reason, isn't good anymore, you throw the exception, which you diligently catch.
In that case, you have all your ducks in a row, and know that there's nothing more you can do (because what was true became false, as if by itself), other than log the exception, send a notification to someone, and tell the customer politely that someone didn't sacrifice their virgins properly during the last full moon, and the problem will be fixed at the first possible moment.
less-enterprisey-suggestion-edit:
If you are doing this for your own pleasure (and the case seems to be this, see comments), I'd suggest returning a boolean instead. The usage would be something like this:
// ...
boolean success = transferTo(otherAccount, ONE_MILLION_DOLLARS_EXCLAMATION);
if (!success) {
UI.showMessage("Aww shucks. You're not that rich");
return; // or something...
} else {
profit();
}
// ...
My rule is
if statements for business logic errors (like your code)
cheched exceptions for environment errors where the application can recover
uncheched exception for environment errors where there is no recovery
Example for checked exception: Network is down for an application that can work offline
Example for uncheched exception: Database is down on a CRUD web application.
There is much documentation on the subject. You can find a lot by browsing the Hibernate
web pages since they changed all exceptions of Hibernate 2.x from checked to unchecked in version 3.x
I recently had a problem with exceptions, code threw NullPointerException and I had no idea why, after some investigation it turned out that real exception was swallowed(it was in new code, so its still being done) and method just returned null. If you do checked exceptions you must understand that bad programmers will just try catch it and ignore exception.
My feeling is that the checked exception is a useful contract that should be used sparingly. The classic example of where I think a checked exception is a good idea is an InterruptedException. My feeling is that I do want to be able to stop a thread / process when I want it to stop, regardless of how long someone has specified to Thread.sleep().
So, trying to answer your specific question, is this something that you absolutely want to make sure that everyone deals with? To my mind, a situation where an Account doesn't have enough money is a serious enough problem that you have to deal with it.
In response to Peter's comment: here's an example using InterruptedException as concrete case of an exception that should be handled and you need to have a useful default handler. Here is what I strongly recommend, certainly at my real job. You should at least do this:
catch (InterruptedException ie) {
Thread.currentThread().interrupt();
}
That handler will ensure that the code catches the checked exception and does exactly what you want: get this thread to stop. Admittedly, if there's another exception handler / eater upstream, it's not impossible that it will handle the exception less well. Even so, FindBugs can help you find those.
Now, reality sets in: you can't necessarily force everyone who writes an exception handler for your checked exception to handle it well. That said, at least you'll be able to "Find Usages" and know where it is used and give some advice.
Short form: you're inflicting a load the users of your method if you use a checked exception. Make sure that there's a good reason for it, recommend a correct handling method and document all this extensively.
From Unchecked Exceptions -- The Controversy:
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.
Note that an unchecked exception is one derived from RuntimeException and a checked exception is one derived from Exception.
Why throw a RuntimeException if a client cannot do anything to recover from the exception? The article explains:
Runtime exceptions represent problems
that are the result of a programming
problem, and as such, the API client
code cannot reasonably be expected to
recover from them or to handle them in
any way. Such problems include
arithmetic exceptions, such as
dividing by zero; pointer exceptions,
such as trying to access an object
through a null reference; and indexing
exceptions, such as attempting to
access an array element through an
index that is too large or too small.
A checked exception means that clients of your class are forced to deal with it by the compiler. Their code cannot compile unless they add a try/catch block.
The designers of C# have decided that unchecked exceptions are preferred.
Or you can follow the C-style and check return values and not throw exceptions.
Exceptions do have a cost, so they shouldn't be used for control flow, as noted earlier. But the one thing they have going for them is that they can't be ignored.
If you decide that in this case to eschew exceptions, you run the risk that a client of your class will ignore the return value or fail to check the balance before trying to transfer.
I'd recommend an unchecked exception, and I'd give it a descriptive name like InsufficientFundsException to make it quite clear what was going on.
Simply put, use checked exception only as part of external contract for a library, and only if the client wants/needs to catch it. Remember, when using checked exception you are forcing yourself on the caller. With runtime exception, if they are well-documented, you are giving the caller a choice.
It is a known problem that checked exceptions are over-used in Java, but it doesn't mean that they are all bad. That's why it is such in integral part of the Spring philosophy, for example (http://www.springsource.org/about)
The advantage of checked exceptions is that the compiler forces the developer to deal with them earlier. The disadvantage, in my mind anyway, is that developers tend to be lazy and impatient, and stub out the exception-handling code with the intention of coming back and fixing it later. Which, of course, rarely happens.
Bruce Eckel, author of Thinking in Java, has a nice essay on this topic.
I don't think the scenario (insufficient funds) warrants throwing an Exception --- it's simply not exceptional enough, and should be handled by the normal control flow of the program. However, if I really had to throw an exception, I would choose a checked exception, by extending Exception, not RuntimeException which is unchecked. This forces me to handle the exception explicitly (I need to declare it to be thrown, or catch it somewhere).
IllegalArgumentException is a subclass of RuntimeException, which makes it an unchecked exception. I would only consider throwing this if the caller has some convenient way of determining whether or not the method arguments are legal. In your particular code, it's not clear if the caller has access to balance, or whether the whole "check balance and transfer funds" is an atomic operation (if it isn't then the caller really has no convenient way of validating the arguments).
EDIT: Clarified my position on throwing IllegalArgumentException.
Line is not always clear, but for me usually RuntimeException = programming errors, checked exceptions = external errors. This is very rough categorization though. Like others say, checked exceptions force you to handle, or at least think for a very tiny fraction of time, about it.
Myself, I prefer using checked exceptions as I can.
If you are an API Developer (back-end developer), use checked exceptions, otherwise, use Runtime exceptions.
Also note that, using Runtime exceptions in some situations is to be considered a big mistake, for example if you are to throw runtime exceptions from your session beans (see : http://m-hewedy.blogspot.com/2010/01/avoid-throwing-runtimeexception-from.html for more info about the problem from using Runtime excpetions in session beans).