Throwing exceptions to control flow - code smell? [closed] - java

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!

Related

How to send successful message to the caller method?

I have a method that is used to save a contact form in database as following, If something goes wrong it throws an exception that will be sent back to the caller of this method.
I am not sure if what I am doing is the best way assure the caller of this method that everything went well.
public boolean saveContact(Contact contact)throws HibernateException{
currentSession().save(contact);
return true;
}
Don't use a boolean flag together with exceptions! Ask yourself if the caller could expect something other as true. The answer is no as in any other case an exception would be thrown. So you will always return true. This doesn't provide any useful information. Even worse, it can lead into a very confusing situation where you return false but no exception was thrown (this cannot happen in your example, as yours is very simple, but I just want to elaborate some cases).
Also note that Hibernate itself doesn't return any things by its currentSession().save(...) method! I would strongly advise to follow this pattern!
And also note that all kinds of boolean flags, error codes or statuses returned by a method are contrary to throw an exception. You shouldn't mix two of those concepts (don't throw an exception in some cases and return a boolean flag in some other cases)!
The absence of an exception should be a success indicator. That is if no exception is thrown the save is successful.So it should be better if you just call save and dont return true.
But still it is good to have a boolean indicator like you already have in your code.
Support at this question too
Much better using this method
public void saveContact(Contact contact) {
currentSession().save(contact);
}

why you need to throw exception in java [closed]

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();
}

Should I use precondition checks to check intermediate results?

Guava offers helper functions to check the preconditions but I could not find helper functions to check intermediate results.
private void foo(String param)
{
checkNotNull(param, "Required parameter is not set");
int x = get(param);
if (x == -1) {
throw new RuntimeException("This should never have happened and indicates a bug.");
}
}
Should I wrap the if (...) {....} part in my own helper?
Or should I use checkState from Guava?
Or should I view the failure of get() as a consequence of param and use checkArgument?
Should I use asserts in these cases?
Or am I missing something?
It's somewhere between a matter of preference and a matter of convention.
Generally, people will use asserts to indicate programming errors; that is, "if I did my job right, then a non-null param should never result in a -1 from get, regardless of user input or other outside forces." I treat them almost as comments that can optionally be verified at runtime.
On the other hand, if get might return -1 in some cases, but that input is invalid, then I would generally throw an IllegalArgumentException, and checkArgument is a perfectly reasonable way to do this. One drawback this has is that when you later catch that, it could have come from pretty much anywhere. Consider:
try {
baz();
bar();
foo(myInput);
} catch (IllegalArgumentException e) {
// Where did this come from!?
// It could have come from foo(myInput), or baz(), or bar(),
// or some method that any of them invoked, or really anywhere
// in that stack.
// It could be something totally unrelated to user input, just
// a bug somewhere in my code.
// Handle it somehow...
}
In cases where that matters -- for instance, you want to pop up a helpful note to the user that they're not allowed to enter -1 in their input form -- you may want to throw a custom exception so that you can more easily catch it later:
try {
baz();
bar();
foo(myInput);
} catch (BadUserInputException e) {
reportError("Bad input: " + e.getMessage());
log.info("recorded bad user input", e);
}
As for checkState, it doesn't really sound right to me. That exception usually implies that the problem was the state that this was in (or some other, more global state in the application). From the docs:
Signals that a method has been invoked at an illegal or inappropriate time.
In your case, a -1 is never appropriate, so checkState is misleading. Now, if it had been:
if (x == -1 && (!allowNegativeOne()) { ... }
...then that would be more appropriate, though it still has the drawback that IllegalArgumentException had above.
So, lastly, there's the question of whether you should just keep the if as it is, or use a helper method. That really comes down to taste, how complex the check is, and how often it's used (e.g. in other methods). If the check is as simple as x == -1 and that check isn't ever performed by other methods (so code reuse is not an issue), I would just keep the if.
If the get method is simply converting the string to an int, then it should do the validation there, preferably throwing an illegalArgumentException or some such RuntimeException. With the above you are also mixing levels of abstraction in your method. E.g. your checkNotNull abstracts away the checking of param for null, but the checking for param as an int is split across the get method and the foo method. Why not have one checkPreCondition type method? E.g.
private void paramShouldBeNonNullInt(String value) {
if (value == null) throw new IllegalArgumentException("value was null");
try {
Integer.parseInt(value)
} catch (NumberFormatException e) {
throw new IllegalArgumentException("value was not an integer");
}
}
First of all you need to make a distinction between contracts (e.g assertions/programming errors) and error handling (e.g. recoverable exceptions that could and should be caught and recovered from).
If you have the need to check an intermediate result, it seems like you don't trust the invoked service and you want to make sure your assumptions hold. Right? This should be expressed as an assertion, and Guava don't have very good support for that.
Have a look at valid4j. Found here https://github.com/helsing/valid4j and here http://www.valid4j.org.
I would then have expressed the code like this (using valid4j's support for hamcrest-matchers):
private int getFoo(String param) {
require(param, notNullValue()); // Violation means programming error at client
int x = get(param);
ensure(x, not(equalTo(-1)); // Violation means programming error at supplier
return x;
}
Some other excellent answers here.
From the Preconditions javadoc:
Precondition exceptions are used to signal that the calling method has made an error. (...) Postcondition or other invariant failures should not throw these types of exceptions.
So ...
Should I wrap the if (...) {....} part in my own helper?
No, existing facilities should be good enough.
Or should I use checkState from Guava?
Yes possibly: if parameters need to be loaded from a file before this method is called, then that would be part of the contract of how this class must be used.
Or should I view the failure of get() as a consequence of param and use checkArgument?
Yes possibly: e.g. if there was some formatting restriction on the syntax of parameters. (Although perhaps that would go inside get())
Should I use asserts in these cases?
Yes. If it's not a precondition check like the above, then normally I'd just use an assert here. Don't forget you can still add a message:
assert x != 1 : "Indicates a bug.";
I find this appropriate to document expectations and verify the internal / private implementation of a class or method.
If you want to make that a runtime check, you could do if (...) throw AssertionError but that's probably only necessary if you're working with dodgy code that you don't trust.

Is returning null after exception is caught bad design [closed]

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.

What's Your ShouldNeverHappenException? [closed]

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.

Categories