Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
Java's checked exceptions sometimes force you to catch a checked exception that you believe will never be thrown. Best practice dictates that you wrap that in an unchecked exception and rethrow it, just in case. What exception class do you wrap with in that case?
What exception would you wrap with in the "// Should never happen" case?
I don't yet have one, but I'd do it the following way:
have it extend Error rather then Exception/RuntimeException, since then it's less likely to be caught by an error handler which is not prepared for it;
wrap it in some static utility calls:
Example:
public static void doAssert(boolean result, String reason) {
if ( !result )
throw new OMGWereDoomedError("Assertion failed: " + reason + " .");
}
I prefer these wrapper since I can then change the implementation if needed.
Also, I don't advocate using assertions since I don't always control the runtime flags, but I do want execution to halt abruptly if the system is compromised.
Consider this:
showing the user a Sorry, we're unable to process your payment page;
confirming the result to the user, even though the system is in an uncertain state.
Which would you choose?
For example, my caveat is the to-UTF-8-bytes character conversion
String.getBytes("UTF-8");
And the need to always wrap it in try-catch as it is a generic method. As UTF-8 could be regarded as standard, I would expect to have a direct String.getUTF8() like call on string, similarly the GetStringUTF8Bytes JNI method.
Of course it could be replaced by a static Charset.UTF8 constant for example and use the getBytes() with that.
Second annoyance for me is the need to wrap the close() into a try-catch. Maybe I'm not that experienced but can't see how it helps when you have already a problem with the stream and you can't even silently close it down for good. You'd practically just log and ignore the exception.
Apparently, you can use a suppressor method call to do just that.
There are also the trivial value-string conversions when you are 100% sure the string is a valid value as you checked it with regex or schema validation.
I use AssertionError with the string This should never happen.
Any class that is a RuntimeException or a descendant of that doesn't need to be put in the method's throws clause. So if you don't want someone to have to deal with it because it shouldn't happen then use that.
It makes sense for things like "Can't connect to the database" because if your database isn't available your application won't run. So you throw a Runtime exception and the person starting the application sees it as a problem. But you don't need to declare it in your throws all the way up the call stack.
ImpossibleHappenedException
I like "Unreachable code reached"
This applies more to the original version of the question, before the question was edited to deal specifically with catching checked exceptions.
Disclaimer: I originally posted a snippet of this in a comment on the question because the question was closed at that point in time.
int salary = ...;
if (salary == 0) {
// ...
} else if (salary < 0) {
// ...
} else if (salary > 0) {
// ...
} else {
throw new IllegalStateException("The fundamental mathematics of the universe have been compromised");
}
Should never happen is an Error more than an Exception. An exception describes a situation, that you possibly can handle. How do you want to handle the unexpected? And as it is an assertion, that this particular exception should never happen, I would use an AssertionError.
Conditions which should never happen unless the code is not correct should be checked with assertions. That way you can disable them in production builds.
But I don't like to leave a simple assert false; and neither do I want to write silly messages like default case in switch should never fire, x should be nonnull, *this should never happen". It shouldn't, but it did. Whatever. Besides, doesn't it sound a little bit whining when you see a message complaining that something shouldn't have ? Also I wouldn't like to have tons of those messages in the executable, as they are generally never used, and each of them is relevant only to some one small function, out of thousands of functions.
So I do like
assert false : "Programming Error"
Programming error is exactly what prevented the application from working so it fits perfectly the situation.
switch (x)
{
case GO_FORWARD:
... break
case BUY_SWORD;
... break
default:
assert false : "Programming Error"
}
/* at this point, we have already had checked that
we have the money */
try {
buy_sword(); buy_elixir();
} catch (InsufficientFunds) {
/* if the code was correct, the funds would be sufficient
so this event means the code is broken. Telling
the user something like "Funds should be sufficient"
won't be helpful to the user, so we put in a generic error message */
throw new AssertionError("Programming Error");
}
If you want to run these checks at all times, then instead of
assert false : "Programming Error"
assert expr : "Programming Error"
do
if (! expr)
throw new Exception("Programming Error")
or even derive ProgrammingError exception class.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
During a code review, another dev and I had a small debate about the proper or correct way to handle multiple returns, and if assigning a pointer to null, and then setting it yields any difference compared to simply returning the value, an later returning null.
private ServiceParam getRequestServiceParam(SlingHttpServletRequest request) {
ServiceParam sp = null;
try {
sp = new ServiceParam(IOUtils.toString(request.getReader()));
} catch (IOException e) {
LOGGER.error("IOException", e);
}
return sp;
}
vs
private ServiceParam getRequestServiceParam(SlingHttpServletRequest request) {
try {
return new ServiceParam(IOUtils.toString(request.getReader()));
} catch (IOException e) {
LOGGER.error("IOException", e);
}
return null;
}
Functionally they seem identical, but we don't know if one my be more correct than the other. Though I fear that this may just be a tabs vs spaces argument.
Whether more than one return from a method is ok or not is a matter of opinion. But there are trade-offs here to talk about where some of the solutions are better than others. Sonarqube complaints are a good place to start, but there are larger issues.
Some people think it's bad to have more than one return and they want to follow the structured programming rules no matter what. Structured programming is better than using goto, and it does produce consistent-looking code.
Other people point out that enforcing one return makes control statement nesting deeper, resulting in code that is harder to read. In the case of the first example I find myself scanning up and down in the method looking for where the local variable gets a value assigned to it, and I think that's annoying.
(Sonarqube doesn't count cyclomatic complexity correctly when you have multiple returns, btw. So if it nags you to avoid that practice maybe there is an element of self-interest there; it's telling you, don't go writing code that we have trouble figuring out.)
Also there is no performance implication to any of this. It is just a matter of awkward coding and less-than-ideal exception-handling. When you return null you create an opportunity for the calling code to fail to check the reference for null, it would be better to let the exception get thrown.
I would not use Optional for this unless it looked like something I'd use in a monadic context where I'm chaining stuff together and using flatMap to handle the Optional empty cases for me. Otherwise it is annoying to have to wrap and unwrap this, it is a bit better than returning null, only because it forces the calling code to consider the empty case.
In this case the actual awkwardness is caused by reading from the httprequest, which is what throws the IOException. You could add throws IOException to the method and let the exception be thrown. But it would be better to move that code to whatever servlet or web controller is getting the httprequest, and have any IOException thrown by calling it get handled in the same way as whatever else the servlet or controller does gets handled.
Once you move that request-reading code there is no compelling reason for this method to exist at all. Deleting unnecessary code is a good thing.
I would follow #khelwood advice. Use Optional if you don't want to handle the raised exception outside of the function call as indicated by #ControlAltDel
private Optional<ServiceParam> getRequestServiceParam(SlingHttpServletRequest request) {
try {
return Optional.of(new ServiceParam(IOUtils.toString(request.getReader())));
} catch (IOException e) {
LOGGER.error("IOException", e);
return Optional.empty();
}
}
if you must use null I would prefer the second approach
private ServiceParam getRequestServiceParam(SlingHttpServletRequest request) {
try {
return new ServiceParam(IOUtils.toString(request.getReader()));
} catch (IOException e) {
LOGGER.error("IOException", e);
return null;
}
}
because I don't have to think twice everything is stated as is. So no unnecessary variable declaration, no need to remember what is in it. (This argument is also true for the Optional approach.)
Update 1: This is true for two, maybe three return statements in a single method, if there are several return statement other solutions must be considered.
Update 2: There is also a sonar rule squid:S1142
IMHO
Multiple returns are error-prone when it comes to code maintenance. Multiple returns are not the easiest to read.
When it comes to choices like this I always choose the code that is easier to read by someone who didn't write it.
When someone else reads it a year from now they might be in a hurry, working on some emergency, and they want code they can understand fully at a glance.
I strive to write code that is super easy to read, i.e., less risky for someone else to refactor.
It is always good to avoid local variables where ever you can, for better performance. If you are too much concerned about readability, then go with Option 1, else go with Option 2. Have a look at this answer for details about assigning the result to a local variable before returning.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I don't know, why you need to throw exception in java. I can just evaluate the return value. Here is an example:
int logic(int i){
switch(i){
case 0:
return 0;
case 1:
return 1;
default:
throw new Exception();
// return -1;
}
}
In the case of default, I can throw exception object, but I can also can return -1. The two methods can capture it. Why do I need to throw an exception?
My English is not that great, because English is not my main language. If there are something you do not understand, please tell me. Thanks.
Throwing an exception, in suitable cases, has several advantages:
In some cases every possible value of the return type is a meaningful result. There is no spare value to use to represent an error.
An exception can convey a lot more information. It can include a message explaining what went wrong.
Catching exceptions can be done for a block of code. Testing return values has to be done after every call, cluttering the code.
An exception can be passed up the call stack to a method that can better report or process it than the immediate caller.
I don't know, why need exception in java.
Exceptions are used as an indication of run-time failure. For example: Some I/O operation cannot be performed or specified resource is not available. In such cases, JVM will indicate the failure by the means of exceptions.
Throwing exceptions is one thing and handling them is another. In your case you are considering a situation where you are explicitly throwing exception. But what if JVM needs to throw one. There is no mechanism to return values via. JVM.
In the case of default, I can return a value
When you explicitly throw an checked exception, the caller has to either handle it or throw it. As a result, caller is aware that the method is capable of generating exception and it can take appropriate actions to handle it.
Actually there are two types of Exception namely Checked and Unchecked. No need worry to handle Unchecked Exception. But need to handle Checked Exception.
Why do we need checked exception in Java?
Checked exceptions are as much part of your method signature as the
name of the method and its parameters so the exception is part of the
contract that you have with the client code. They serve as a marker to
the client code that you have come across a error situation that you
do not know how to handle or that you want the client code to know
about so that it can handle the problem for you.
Read more.
First, you should never throw new Exception(). This is very bad practice as it encourages catching Exception. This means that all exceptions are treated in the same way by the code, i.e. you catch exceptions that you didn't mean to.
So you should create a custom exception type or use one of the existing ones. Maybe something like an IllegalArgumentException. There is a large debate over when to throw unchecked (exceptions that extend RuntimeException) versus checked exceptions. I won't get into that now.
As for why you would throw an exception rather than return -1, this is due to the nature of exceptions. They "propagate". You can throw them in one method and they automatically get propagated up the call stack until they are caught. This means you can throw an exception in your business layer and propagate it to your GUI layer without having to explicitly return an error code.
Further, what happens when the error is in a void method:
void logic(int i){
switch(i){
case 0:
doSomethingWonderFul();
case 1:
doSomethingEvenMoreWonderFul();
default:
//oops, what now?
}
}
An exception is used to denote a situation in which something exceptional, if you will, has happened and thus requires some special attention. You can return different integer values to denote the terminating state of the different methods you have, but what if you have a method which reads an object from file and returns it?
Your method would require you to:
Have your method return a list of items, thus making your code more complex.
Have some sort of documentation to denote what do the different numbers in your return statement mean. This can be troublesome, especially if you are not careful enough and adopt some sort of standard.
In short, if you have the same method above and use exceptions, you can return just the object you are creating while at the same time point the list of this which can go wrong in the method signature, thus making the code easier to read, follow and maintain.
In short:
public List loadObjectFromFile(String path)
{
List returnList = new ArrayList();
...
//Something goes wrong in your code
returnList.add("1");
}
Then you call it like so:
List loadFromFile = loadObjectFromFile("...");
if(list.get(0).toString().equals("1"))
{
System.out.println("Error ... has occured");
}
...
else if(list.get(0).toString().equals("0"))
{
MyObject obb = loadFromFile.get(1);
}
As opposed to:
public MyObject LoadObject(String filePath) throws Exception
{
...
}
And then call it like so:
try
{
MyObject obj = LoadObject("...");
}
catch (Exception e)
{
e.printStackTrace();
}
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
Joshua Bloch in his Effective Java writes :
"Use the Javadoc #throws tag to document each unchecked exception that
a method can throw, but do not use the throws keyword to include unchecked
exceptions in the method declaration. "
Well that sounds reasonable indeed, but how to find out, what unchecked exception can my method throw?
Let's think of a following class :
public class FooClass {
private MyClass[] myClass;
/**
* Creates new FooClass
*/
public FooClass() {
// code omitted
// do something with myClass
}
/**
* Performs foo operation.<br />
* Whatever is calculated.
* #param index Index of a desired element
* #throws HorribleException When something horrible happens during computation
*/
public void foo(int index) {
try {
myClass[index].doComputation();
} catch (MyComputationException e) {
System.out.println("Something horrible happened during computation");
throw new HorribleException(e);
}
}
}
Now, I documented HorribleException, but it is quite obvious, that foo method can also throw unchecked java.lang.ArrayIndexOutOfBoundsException. The more complex the code gets, it's harder to think of all unchecked exceptions that method can throw. My IDE doesn't help me much there and nor does any tool. Since I don't know any tool for this ...
How do you deal with this kind of situation?
Only document those which you're explicitly throwing yourself or are passing through from another method. The remnant is to be accounted as bugs which are to be fixed by good unit testing and writing solid code.
In this particular case, I'd account ArrayIndexOutOfBoundsException as a bug in your code and I'd fix the code accordingly that it never throws it. I.e. add a check if the array index is in range and handle accordingly by either throwing an exception -which you document- or taking an alternative path.
The more complex the code gets, it's harder to think of all unchecked exceptions that method can throw.
Where you see a problem, I see a very good reason to keep your code simple ;-)
In your exemple, I'd suggest to document the ArrayIndexOutOfBoundsException. Just because that's something someone can have when giving a bad parameter to you method, and it should be written somewhere : "If you given an invalid array index, you'll get an ArrayIndexOutOfBoundsException. For example, the String#charAt() method documents it can throw an IndexOutOfBoundException if the index isn't valid.
In general, you shouldn't document al the exceptions that can arise. You can't predict them all, and you're very likely to forget one. So, document the obvious ones, the one you though of. Try to list the most exceptions as possible, but don't spend to much time on it. After all, if you forget one that should be documented, you can improve your documentation later.
Document only what you're throwing yourself.
In this case, I'd go for a index bounds check and throw my own exception:
throw IllegalArgumentException("Index must be smaller than " +myClass.length + ", but is: " + index)
and then document the IllegalArgumentException in the JavaDoc.
The quote you posted, is just something you have to keep in mind if you want to be the ideal programmer. Programming is not thinking "what can go wrong", but is think how to do something the best way and program it. If it is a personal project, just write what the method does.
However, there are three possible solutions:
Do not document the method.
Think a minute of what your code does and find out what the most common possible unchecked exceptions could be. Add them to the Java-doc. And if you encounters a new one, find out what the problem is and add it as possible exception.
Do not care about the possible exceptions and document only the exceptions you throw in the method body (like: if (obj == null) { throw new NullPointerException(); }).
We have a written checkstyle extension that run on our test server. In your sample it would test if HorribleException was documented.
The ArrayIndexOutOfBoundsException will detect with a code review. In your sample code our goals required to throw a InvalidArgumentException instead a ArrayIndexOutOfBoundsException. The documentation of it will be find from test server.
The ArrayIndexOutOfBoundsException can be a warning in FindBugs. But I am not sure.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I always come across the same problem that when an exception is caught in a function that has a non-void return value I don't know what to return. The following code snippet illustrates my problem.
public Object getObject(){
try{
...
return object;
}
catch(Exception e){
//I have to return something here but what??
return null; // is this a bad design??
}
}
So my questions are:
Is return null bad design?
If so what is seen as a cleaner solution??
thanks.
I would say don't catch the exception if you really can't handle it. And logging isn't considered handling an error. Better to bubble it up to someone who can by throwing the exception.
If you must return a value, and null is the only sensible thing, there's nothing wrong with that. Just document it and make it clear to users what ought to be done. Have a unit test that shows the exception being thrown so developers coming after you can see what the accepted idiom needs to be. It'll also test to make sure that your code throws the exception when it should.
I always come across the same problem that when an exception is caught in a function that has a non-void return value I don't know what to return.
If you don't know what to return, then it means that you don't know how to handle the exception. In that case, re-throw it. Please, don't swallow it silently. And please, don't return null, you don't want to force the caller of the code to write:
Foo foo = bar.getFoo();
if (foo != null) {
// do something with foo
}
This is IMHO a bad design, I personally hate having to write null-checks (many times, null is used where an exception should be thrown instead).
So, as I said, add a throws clause to the method and either totally remote the try/catch block or keep the try/catch if it makes sense (for example if you need to deal with several exceptions) and rethrow the exception as is or wrap it in a custom exception.
Related questions
How to avoid “!= null” statements in Java?
Above all I prefer not to return null. That's something that the user has to explicitly remember to handle as a special case (unless they're expecting a null - is this documented). If they're lucky they'll deference it immediately and suffer an error. If they're unlucky they'll stick it in a collection and suffer the same problem later on.
I think you have two options:
throw an exception. This way the client has to handle it in some fashion (and for this reason I either document it and/or make it checked). Downsides are that exceptions are slow and shouldn't be used for control flow, so I use this for exceptional circumstances (pun intended)
You could make use of the NullObject pattern.
I follow a coding style in which I rarely return a null. If/when I do, that's explicitly documented so clients can cater for it.
Exceptions denote exceptional cases. Assuming your code was supposed to return an object, something must have gone wrong on the way (network error, out of memory, who knows?) and therefore you should not just hush it by returning null.
However, in many cases, you can see in documentation that a method returns a null when such and such condition occurs. The client of that class can then count on this behaviour and handle a null returned, nothing bad about that. See, in this second usage example, it is not an exceptional case - the class is designed to return null under certain conditions - and therefore it's perfectly fine to do so (but do document this intended behaviour).
Thus, at the end of the day, it really depends on whether you can't return the object because of something exceptional in your way, or you simply have no object to return, and it's absolutely fine.
I like the responses that suggest to throw an exception, but that implies that you have designed exception handling into the architecture of your software.
Error handling typically has 3 parts: detection, reporting, and recovery. In my experience, errors fall into classes of severity (the following is an abbreviated list):
Log for debug only
Pause whatever is going on and report to user, waiting for response to continue.
Give up and terminate the program with an apologetic dialogue box.
Your errors should be classified and handling should be as generically and consistently as possible. If you have to consider how to handle each error each time you write some new code, you do not have an effective error handling strategy for your software. I like to have a reporting function which initiates user interaction should continuation be dependent on a user's choice.
The answer as to whether to return a null (a well-worn pattern if I ever saw one) then is dependent on what function logs the error, what can/must the caller do if the function fails and returns the null, and whether or not the severity of the error dictates additional handling.
Exceptions should always be caught by the controller in the end.
Passing a <null> up to the controller makes no sense.
Better to throw/return the original exception up the stack.
It's your code and it's not bad solution. But if you share your code you Shoudn't use it because it can throw unexpected exception (as nullpointer one).
You can of course use
public Object getObject() throws Exception {}
which can give to parent function usable information and will warn that something bad can happen.
Basically I would ditto on Duffymo, with a slight addition:
As he says, if your caller can't handle the exception and recover, then don't catch the exception. Let a higher level function catch it.
If the caller needs to do something but should then appropriately die itself, just rethrow the exception. Like:
SomeObject doStuff()
throws PanicAbortException
{
try
{
int x=functionThatMightThrowException();
... whatever ...
return y;
}
catch (PanicAbortException panic)
{
cleanUpMess();
throw panic; // <-- rethrow the exception
}
}
You might also repackage the exception, like ...
catch (PanicAbortException panic)
{
throw new MoreGenericException("In function xyz: "+panic.getMessage());
}
This is why so much java code is bloated with if (x!=null) {...} clauses. Don't create your own Null Pointer Exceptions.
I would say it is a bad practice. If null is received how do I know if the object is not there or some error happened?
My suggestion is
never ever return NULL if the written type is an array or
Collection. Instead, return an empty Collection or an empty array.
When the return type is an object, it is up to you to return null depending on the scenario. But never ever swallow an exception and return NULL.
Also if you are returning NULL in any scenario, ensure that this is documented in the method.
As Josha Blooch says in the book "Effective Java", the null is a keyword of Java.
This word identifies a memory location without pointer to any other memory location: In my opinion it's better to coding with the separation of behavior about the functional domain (example: you wait for an object of kind A but you receive an object of kind B) and behavior of low-level domain (example: the unavailability of memory).
In your example, I would modify code as :
public Object getObject(){
Object objectReturned=new Object();
try{
/**business logic*/
}
catch(Exception e){
//logging and eventual logic leaving the current ojbect (this) in a consistent state
}
return objectReturned;
}
The disadvantage is to create a complete Object in every call of getObject() (then in situation where the object returned is not read or write).
But I prefer to have same object useless than a NullPointerException because sometimes this exception is very hard to fix.
Some thoughts on how to handle Exceptions
Whether returning null would be good or bad design depends on the Exception and where this snippet is placed in your system.
If the Exception is a NullPointerException you probably apply the catch block somewhat obtrusive (as flow control).
If it is something like IOException and you can't do anything against the reason, you should throw the Exception to the controller.
If the controller is a facade of a component he, translate the Exception to well documented component-specific set of possible Exceptions, that may occur at the interface. And for detailed information you should include the original Exception as nested Exception.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
Consider this code (Java, specifically):
public int doSomething()
{
doA();
try {
doB();
} catch (MyException e) {
return ERROR;
}
doC();
return SUCCESS;
}
Where doB() is defined as:
private void doB() throws MyException
Basically, MyException exists only in case doB() meets some condition (which is not catastrophic, but does need to somehow raise this condition) so that doSomething() will know to exit with an error.
Do you find the use of an exception, in this case to control flow, acceptable? Or is this a code smell? If so, how would you refactor this?
Is it really important for doC() to be executed when doB() fails? If not, why not simply let the Exception propagate up the stack to where it can be handled effectively. Personally, I consider using error codes a code smell.
Edit: In your comment, you have described exactly the scenarion where you should simply declare
public void doSomething() throws MyException
It entirely depends on what that error condition is, and what the method's job is. If returning ERROR is a valid way of handling that error for the calling function, why would it be bad?
Often, however, it is a smell. Consider this:
bool isDouble(string someString) {
try {
double d = Convert.ParseInt32(someString);
} catch(FormatException e) {
return false;
}
return true;
}
That is a very big code smell, because you don't expect a double value. You just want to know whether a string contains a double.
Sometimes, the framework you use doesn't have other ways of doing what you want. For the above, there is a better way:
bool isDouble(string someString) {
bool success;
Convert.TryParseInt32(someString, ref success);
return success;
}
Those kinds of exceptions have a special name, coined by someone whose blog I read recently, but sadly, I forgot its name. Please comment if you know it. Last but not least, the above is pseudocode. I'm not a C# developer so the above doesn't compile, I'm sure, but TryParseInt32 / ParseInt32 demonstrates that well I think, so I'm going with C#.
Now, to your code. Let's inspect two functions. One smells, and the other doesn't:
1. Smell
public int setupSystem() {
doA();
try { doB(); }
catch (MyException e)
{ return ERROR; }
doC();
return SUCCESS;
}
That's a code smell, because when you want to setup a system, you don't want it to fail. Failing to setup a system means you can't continue without handling that error.
2. OK
public int pingWorkstation() {
doA();
try { doB(); }
catch (MyException e)
{ return ERROR; }
doC();
return SUCCESS;
}
That is OK, because the purpose of that method is to test whether the workstation is still reachable. If it's not, then that is part of the result of that method, and not an exceptional case that needs an alternative return path.
My only problem with the OP's code is that you're mixing paradigms -- doB shows an error by throwing an exception, while doSomething shows an error by returning a code. Ideally, you would pick one or the other. Of course, in legacy maintenance, you might not have that luxury.
If you pick returning error codes, that's OK, but I dislike it because it encourages you to use side channels (like global variables) to communicate state on failure, rather than bundling that state into an exception and letting it bubble up the stack until you can do something about it.
I've never liked using exceptions for control flow (in some languages, like the CLR, they're expensive).
If you can modify doB(), the best thing to do is change it to return a boolean that indicates success or failure, so your example would look like:
public int doSomething()
{
doA();
if (!doB()) {
return ERROR;
}
doC();
return SUCCESS;
}
Exceptions should be used when:
a function cannot complete normally, and
when there is no return value that can be used to indicate the failure, or
when the thrown exception communicates more information than return FAILURE; can, for instance, nested exceptions or the like.
Remember above all that exceptions, like return values or method parameters, are simply messages sent between different parts of the code. Strive to optimize the balance between the information communicated via these methods, and the simplicity of the API. When a simple SUCCESS/FAILURE flag is all that's needed (and the method doesn't need to return other values), use that. If the method already must return a value, you usually need to use an exception (which is, to one way of looking at it, simply an "exceptional" return value from the method). If the failure information that must be communicated is too rich to be communicated in a return value (for instance, the reason for an I/O failure), use an exception.
Finally, error handling is a design decision, and there is no one-size-fits-all set of rules that will cover all cases.
Using exceptions to control flow, is definitely bad. Exceptions should be thrown only in exceptional conditions.
However, having a utility method that simply either throws an exception or does nothing is not particularly bad. For example, you may wish to validate all the arguments on entry to a method, or check that internal state is still valid between complex calculations (that for some reason you cannot force internally, perhaps you're accepting closures and executing them). In these cases it would not be a bad idea to extract the consistency checking into its own method, to improve the readability of the "actual" method implementation.
The dividing line is really that you should throw an exception when something outside of normal operating parameters is encountered, and things are so bad that there's no real way for the method to proceed with what it does.
As an example of what not to do, this would be using exceptions for flow control:
public int calculateArraySize(Object[] array)
{
int i = 0;
try
{
array[i++];
}
catch (ArrayIndexOutOfBoundsException ignore) {}
return i;
}
I believe it will return the right result, but it will be horribly slow and inefficient, as well as difficult to read for people who are used to exceptions being used properly. ;-)
On the other hand, something like this would be OK in my opinion:
public void myMethod(int count, Foobar foo) throws MyPackageException
{
validateArgs(count, foo);
// Stuff
}
private void validateArgs(int count, Foobar foo) throws MyPackageException
{
if (m_isClosed)
{
throw new IllegalStateException("Cannot call methods on a closed widget");
}
if (count < 0)
{
throw new IllegalArgumentException("count must be greater than zero");
}
foo.normalise(); // throws MyPackageException if foo is not fully initialised at this point
}
Despite the fact that all the second method does is potentially throw an exception, it's not doing this to control the program flow but is raising them in response to exceptional conditions.
It's ok to throw Exception in case of error, as in doB().
But problem is function doSomething().
You shouldn't use return statements to indicete success or failure. You should do:
try {
doB();
} catch (MyException e) {
throw MyException2(e);
}
Exceptions should not be used just to control flow. Checked exceptions should be used to tell calling code that certain conditions of the API contract were not met. I would not design doSomething to handle cases where calls to doB would fail often by using a try/catch block. If frequent failure was a case that you needed to deal with, I would design doB to return a success or failure boolean to indicate to its calling methods whether to continue on to their own doC-type methods:
public int doSomething() {
doA();
if ( doB() )
doC();
return SUCCESS;
} else {
return ERROR;
}
}
Depending on doB's logic, you could have some return values pointing if it was ok or not, and then doSomething could use the returned value to handle the situation in an appropriate way.
Exceptions are for non-standard behaviour. So yes it is ok to use them for controlling flow.
As Sun puts it:
Generally speaking, do not throw a RuntimeException or create a subclass of RuntimeException simply because you don't want to be bothered with specifying the exceptions your methods can throw.
Here's the bottom line guideline: 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.
Just remember to not subclass RuntimeException but Exception as those are faster.
I think it is very bad use of exceptions, plain and simple. I would create normal functions that return normal values and leave exceptions to what they are designed for.
As others have indicated, it really depends on the intended functionality of the methods involved here. If doSomething()'s role is to check something, returning a code that allows normal execution of its calling methods to continue (albeit on different paths depending on the code returned) then having it return that int may be fine. In that case, though, doB() should probably be consistent and return a boolean or something that doSomething() can check instead of throwing an exception which won't really do anything else.
If doB() were a public method of a another class that might have other uses outside of doSomething() (as opposed to a private method in the same class as you indicated) and it throws an exception and you want to use it in doSomething() (which has the same role indicated above), then your example would be fine.
The fact that the code you return when doB() throws an exception is called ERROR, though, indicates that it's probably a failure that would prevent whatever operation doSomething() is a part of from completing. In that case, you should probably not catch the exception thrown by doB() and just let it be thrown up the stack until it reaches a point where it can be handled or until it reaches your general error handler which can report/log it or whatever.
In C#, throwing exceptions is relatively expensive, performance-wise – thus another reason to avoid their use for flow control. Is that the case in Java? Yes, there's an argument to be made for not over-analyzing performance ahead of time. But if you know something will take extra time, and its easy to avoid, shouldn't you do it? Unless you truly don't care!
See the top answer to this question:
How slow are Java exceptions?
It turns out they're at least 50 times slower than normal code flow. So I'd say that using exceptions in the usual run of code is definitely a bad idea.
Here is how I would handle it:
public void doSomething()
throws MyException{
doA();
try {
doB();
} finally {
doC();
}
}
If an error occurs in doB(), the exception will propagate up the stack.
You guys are killing me here. You NEVER want to use exceptions to control flow. It wouldn't be much different than using goto statments everywhere!
Exceptions are exception, meaning something un expected has happened. Something so much so we are halting the execution of the application. Anyone who has worked on an application were this type of exception flow control is baked in will want to hunt down the developer who did this and throttle him (or her).
Using exception as flow control makes maintainence and new feature development a nightmare!