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.
Related
I have quite a lot of experience with java (math, UIs and graphics mostly), but I've never seriously worked with APIs like JDBC or org.w3c.dom where you are heavily relied on handling checked runtime exceptions. So if I write a bunch of methods woriking with those kind of APIs, how do I decide what should I do with exceptions, whether I should catch them right away or add them to method's signature and thus propatate exceptions to a higher level of the frame stack, where they all are handled? It seems that all I would ever want to do with those checked exceptions is to exit the application with an error whenever one is encountered.
Generally, exceptions fall into two buckets: 1) the type you can recover from in some meaningful way. 2) the type that indicates failure and possibly a need to communicate that (logging, return some error page, display a dialog, etc.).
The former you handle close to where the exception happens (e.g. retry an http REST call), the latter you preferably handle in one place instead of littering your code with catch blocks.
Validation related exceptions in web applications are a good example of the type that you don't handle and instead you let the web application trap them and then map them to a status 400 response code.
Another example: Java throws a checked exception on just about anything that takes a character encoding. Generally you just want to pass in "utf-8" and unless you mistype that, that exception will never happen. If it does happen, it means UTF-8 is apparently no longer supported. I don't see how you could recover from that in a meaningful way. I tend to catch and rethrow these as unchecked exceptions. They'll never happen but when they do, I want the software to fail with an exception so that it gets logged somewhere.
So, if some code you are using throws a checked exception, you need to decide if you can recover from it locally. If not, you need to decide if somebody up the call stack should want/need to know about or handle the exception. If so, add it to your throws and move the decision up the callstack. If not, rethrow it as an unchecked exception and handle it somewhere centrally (e.g. log it).
This question is a bit difficult to answer.
Lets say, you are going to the market to buy something, but you don't have cash in your valet. What you have is an ATM card of some bank, but again you are not sure of whether there is enough money in your account to do the shopping.
Now, there are two things you can do here. Either,
1) You first make sure that you do have sufficient money in your account before leaving to the Market, OR
2) Reach out to the market and then see, if you can buy any items.
Likewise, In java there are two types of Exceptions
Checked Exception which is a sub-class of java.lang.Exception, and
Unchecked Exception which is a sub-class of java.lang.RuntimeException.
Checked Exceptions can be thought of synonymous to the first case of you going to shopping. Here after finding that you don't have enough balance to do the shopping, either you can decide to borrow it from someone OR do nothing, that is, quit the plan of shopping for now.
Similarly, Unchecked Exception can be thought of as you going to the market without knowing about the balance in your account. Now, at the billing counter either your transaction will be successful OR it will be declined because you don't have enough balance in your account. Here also, either you can decide to just apologize to the shop-keeper and get going OR you can call someone to bring the required money to the shop.
As you can see, what you may do in such situations is totally dependent on you.
Similarly, In programming with Java there is not much difference between the Checked and Unchecked Exception and what you want to do if Exceptions occurred is totally dependent on your personal/organizations policies.
The Java compiler only mandates this that in case of a method throwing Checked Exception, your code using that method must have to catch the Exception OR throw it one level up. While in case of Unchecked Exceptions, this is optional.
Take for Example the following method which throws a Checked Exception :
// Here compiler makes sure that you either catch exception OR declare it to be thrown
public void storeDataFromUrl(String url){
try {
String data = readDataFromUrl(url);
} catch (BadUrlException e) {
e.printStackTrace();
}
}
// Here BadUrlException is a subclass of Exception
public String readDataFromUrl(String url) throws BadUrlException{
if(isUrlBad(url)){
throw new BadUrlException("Bad URL: " + url);
}
String data = null;
//read lots of data over HTTP and return it as a String instance.
return data;
}
Now your storDataFromUrl() method can either catch the BadUrlException OR it can declare it to b throw, in which case the code using the storeDataFromUrl() method will have to do the same thing. That is, either catch the exception or throw it for someone higher to deal with it as they would like.
And now the same example, which throws an Unchecked exception;
// Here compiler does not force you to either catch exception OR declare it to be thrown
public void storeDataFromUrl(String url){
String data = readDataFromUrl(url);
}
// Here BadUrlException is a subclass of RuntimeException
public String readDataFromUrl(String url) { // Notice, it does not have a throws clause
if(isUrlBad(url)){
throw new BadUrlException("Bad URL: " + url);
}
String data = null;
//read lots of data over HTTP and return it as a String instance.
return data;
}
FEW POINTS Most of the Books advice you to use checked exceptions for all errors the application can recover from, and unchecked exceptions for the errors the application cannot recover from.
In reality most applications will have to recover from pretty much all exceptions including NullPointerException, IllegalArgumentExceptions and many other unchecked exceptions. The action / transaction that failed will be aborted but the application has to stay alive and be ready to serve the next action / transaction. The only time it is normally legal to shut down an application is during startup. For instance, if a configuration file is missing and the application cannot do anything sensible without it, then it is legal to shut down the application.
EDIT : Yo can read these two articles for more understanding on the topic : Three rules for effective exception handling and Best Practices for Exception Handling
The right spot to handle exception depends entirely on the concrete situation. If you just want to exit the application don't catch the exceptions but declare them in the throws clause.
For a server program however, this would not be a good strategy. For example, you don't want your server to crash whenever the DB is not reachable because of a short network problem.
Well,this is a difficult question.One of the five modularity criteria from B.Meyer book is Protection.This criterion says that if an error apear in a class,or a module,it should not spread in the hole system.So the error must be isolated from the other component of the system.
Therefor I think you should catch the exception on a low level in the system.
If exception indicates problem that is caused by external sources like problem with network, bad format of xml etc. (it depends on exception type). then you should catch such exception where you can do something about it - if thats GUI application, then catch it where you can show error dialog to user - and make him/her make decision. If thats on server, then log error - return it to client. If exception is due to programming bug, then on GUI application you can log it / or allow user to send it in email to user. For command line tool I would allow application to exit with exception and throw all its data to output, if thats GUI application - I would rather try to catch it and try to recover with giving hint to user that there is a problem.
You could also add global exception handler to your program that will automatically send such exceptions to your email.
Should exceptions without messages ever be thrown? In what cases? For example, when subclassing Exception, should a constructor with no parameters even be given?
public class LexerException extends Exception {
public LexerException(String message) {
super(message);
}
}
or
public class LexerException extends Exception {
public LexerException() {
super();
}
public LexerException(String message) {
super(message);
}
}
Should exceptions without messages ever be thrown? In what cases?
An exception without a message will be thrown any time some code instantiates and throws an exception without a message. Anyone can write code like that.
Of course, if the exception that you are trying to throw does not allow you to instantiate it without a message ... or a with null message ... then you can't. But I've never come across an exception class that insists that the exception is non-null.
One case where exceptions typically have no message is NullPointerException when it is thrown by the JVM itself.
If you are asking should it ... in the sense of whether it is good practice to write code that throws exceptions without a message, the answer is (IMO) No. But you can make up your own mind. (I guess, if the exception name says all that there is to be said, then a message would be redundant. However, it is always useful to have extra information in the stacktrace when debugging.)
Re these comments:
Generally, you should avoid custom exceptions. Use ones that already exist. ā mre
Why should I avoid custom exceptions? ā Kyranstar
The point is that before you code a custom exception, you should look to see if there is an existing exception that means the same thing as your proposed new one. For example, don't write a custom IllegalLexerArgumentException exception when there is an existing IllegalArgumentException that would serve your purposes.
Why?
For the same reasons that we don't write (say) custom collection classes without good reason. It is a bad idea to write unnecessary code, 'cos that is just more code to compile and test, more space at runtime, more code for the maintainer to read, etc.
Because having lots of exception classes that mean the same thing can make exception handling messy. This effect gets worse as you combine / reuse more libraries to make large applications.
If you don't give the exception any message so you can pop-up the message into anther position when you get the error, but it's recommended to give every exception you create a message and to create an instance of this exception and to throw it.
If the documentation explicitly states there is a single case triggering the exception, then IMHO it is not require to have a message in the exception. Otherwise, it is. A good rule of thumb is: Make it easy for whoever is going to use/debug that code.
Well, honestly I've just searched our code and we use Exceptions without messages, but they are really obvious ones. Like:
UsernameCantBeEmptyException// example only
I think this depends on the use case. The NullPointerException for instance has no message. What could be helpful? No idea. On the other hand there where versions of java where the ClassCastException had no message. That's extremly annoing as the type that should be casted is hart to figure out and is available to the program.
As long as I've no idea for a use case where skipping the message seems appropiate, I'd provide no empty constructor. AFAIK a lexer figures out things like this variable has that type and thus that acion is appropriate or not. This would indicate that the exception message might even have to be presented to he end user. In such a case even localization might be mandatory. If so even some 'factory infrastructre' might be a good idea.
On custom exceptions in general: There's been a tendency to do that to often and then many figured out that in fact no custom exceptions have ever been needed. And in fact there are even hudge programs that need not a single one. On business I work on a 200kLOC program and I don't think we have one. But for sub-systems with specific needs on handling (Like catching all the LexerException to show them in a specific way, separate them from programming bugs in your own code, whatsoever) it might make much sense to have a few. I'm working on a small OSS project and there I have even more than one. But you should always keep in mind that additional exception type must make the exception handling simpler not more complicated. If you often have several catch block one after another, then your definitly on the wrong track. That's a typical symptom of unnecessary custom exceptions.
I am going through a Spring book to learn Spring. Having gone through sections about the JDBCTemplate i was surprised to find that Spring handles most of the SQLException exceptions differently.
For example, all checked exceptions are converted to unchecked exceptions. What exactly is the benefit of this?
In my experience, the majority of SQL exceptions should be handled. For example, we have an application that talks to an Oracle PL/SQL procedure. The call to the PL/SQL procedure can return an ORA-01403: no data found exception. This kind of exception is one that you usually recover from by displaying an error message to the user. e.g. A search result did not return anything.
How would this kind of a checked exception be handled in Spring if all exceptions are unchecked i.e. Spring wont force you to handle them?
I know that you can catch RuntimeExceptions but i quite liked the idea that you are forced to handle checked exceptions. What benefit does converting some of the checked exceptions to unchecked exceptions provide?
Yes, the exceptions should be handled, but in Spring design, on higher level then the each DAO method. In fact the design where in every method there is SQLException handling is unclean copy-paste design, and when you change something, you must apply the change in every place.
There are various demands, and various places where you handle unchecked exceptions. One of these are aspects, where you can for example convert Spring's exceptions to your exceptions (uncatched exceptions need not be declared in method signature, so this convertion is very elegant). In REST method you can add generic handler that will return the error responce to the caller, and you write exception handling in only one place. In JSF/JSP based technologies you can add own error page whenever error occures.
Some people don't like checked exceptions, as they force you to do some exception management. I guess the Spring guys are of this kind.
Personally I prefer to do things as they were intended to be made:
try {
// execute some SQL
} catch (SQLException ex) {
if (ex is an expected condition) {
// deal with it: for example with a "no data found" condition
// this might mean returning null, or throwing some kind of business exception, such as
// NoEmployeeFoundException, or whatever
} else {
// this is a programming / environment error
// throw as unchecked exception
throw new RuntimeException(ex);
}
}
Of course the downside of this approach is that is more work. The upside is that you have explicitly stated in code which are the "expected" circumstances and which ones should not happen ever.
The benefit is not being forced to catch or declare them.
I'm not convinced that not finding data during user searches is exceptional, particularly at the SQL level. Turning that into a checked exception amounts to using exceptions for generalized flow control. I would consider that an anti-pattern to be avoided; YMMV.
Many SQL-related errors are code-related; IMO it's better to fail fast--during development.
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).
At what point would you create your own exception class vs. using java.lang.Exception? (All the time? Only if it will be used outside the package? Only if it must contain advanced logic? etc...)
I think you need to ask yourself a slighly different question "What advantage does creating a new exception give me or developers who use my code?" Really the only advantage it gives you or other people is the ability to handle the exception. That seems like an obvious answer but really it's not. You should only be handling exceptions that you can reasonably recover from. If the exception you throw is a truly fatal error why give developers a chance to mis-handle it?
More in depth discussion: Custom exceptions: When should you create them?
Reason one:
Need to catch specific stuff. If calling code needs to deal with a specific exceptional condition, you need to differentiate your Exception, and Java differentiates exceptions with different types, so you need to write your own.
Basically, if someone has to write:
catch(ExistingException e) {
if({condition}) {
{ some stuff here}
}
else {
{ different stuff here}
}
}
You probably want to write a specific extension; catch Exception matching is clearer than conditionals, IMHO.
Remember: your new Exception can be a subclass of RuntimeException
Reason two:
API consolidation. If you write an interface and you have several implementations, it's possible that they will call different APIs with a whole bunch of different non-RuntimeExceptions thrown:
interface MyInterface {
void methodA();
}
class MyImplA {
void methodA() throws SQLException { ... }
}
class MyImplB {
void methodA() throws IOException { ... }
}
Do you really want MyInterface.methodA to throw SQLException and IOException? Maybe then it makes sense to wrap the possible exceptions in a custom Exception. Which again can be a RuntimeException. Or even RuntimeException itself...
I believe that:
catch (Exception e) {
...
}
... is an antipattern that should be avoided. You might want one centralized broad catch somewhere in your application, to log an error and prevent the whole application from terminating - but having them scattered around willy-nilly is bad.
Why:
try {
if(myShape.isHidden()) {
throw new Exception();
}
// More logic
} catch (Exception e) {
MyApp.notify("Can't munge a hidden shape");
}
So you try this, and due to a coding error, myShape is null. A NullPointerException gets thrown when the runtime tries to derefence myShape. This code reports a hidden shape, when it should be reporting a null pointer.
Either make your own exception, or find a suitably specialized exception in the API. It's not as if extending Exception or RuntimeException is onerous.
When I want to treat my exceptions differently from everybody else's. If I want to catch mine and propagate everyone else's, or if I want to catch someone else's and propagate mine, or if I want to catch both but treat them differently, then I will define a separate class for my exceptions. If I want to treat them all the same, either by propagating both or by catching both (and doing the same thing either way with the caught exceptions), the I will use the standard class.
IF there is an existing Exception with the language runtime or libraries, use it ELSE create your own, document it well and that should work in 99% of the cases.
Software captures meaning.
There are almost no reasons for throwing an existing exception: the JVM already does that for you. Your version of their exception isn't really accurate and throwing "Exception" isn't meaningful, either.
You might have a DataFormatException because of a parsing algorithm you wrote. This, however, is rare.
When your program encounters an exceptional situation, it's almost always unique to your program. Why force-fit your exceptional situation into an existing exception? If it's unique to your program, then... well... it's unique. Name it that way.
Do not, however, provide a unique exception class for each unique message. One exception class can have many variant messages and supporting details.
The Python rule of thumb, translated to Java, is to define any unique exceptions at the package level. [In Python, they suggest exceptions at the "module" level, something that doesn't precisely translate to Java.]
Start always by using the common exception classes and then when a need appears to handle it specially, change it.
When creating a method first time, just let exceptions go through.
If there are exceptions that must be handled, those can either be just defined in throws or wrapped to some runtime exception or wrapped own throws exception. I prefer runtime exceptions in many cases. Defining throws definition should be avoided until there is a need for it from API point of view.
Later when a need appears to do specific handling for an exception in some caller, come back and create new exception for it.
The point is to avoid doing extra work before knowing what is needed.
I can't imagine specifically throwing a java.lang.Exception if some object/class/method had a problem. It's too generic - if you're not going to create your own Exception class, seems to me like there ought to at least be a more specific Exception-type in the API.
I would use the exceptions from the Java API when the exception relates to the API. But if an exceptional situation arises that is unique to my own API then I will create an Exception for it. For example if I have a Range object with two properties min and max and the invariant min <= max then I will create an exception InvalidRangeException.
When I am writing code this helps because I know if the exception originates because I violated one of my own conditions or its something from the Java API.
In most cases it doesn't make sense to create your own exception class.
There is a tendency in novice programmers to create their own exception class just so they can use a name that is more indicative of the type of error. So you'll find classes like FTPInitializationException, DAOFactoryException etc. even though such exceptions are not being handled differently than standard exceptions. This is clearly an anti pattern that should be avoided.