How to send successful message to the caller method? - java

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

Related

Shouldn't catch NPE but don't know how to handle the NULL

I know that NPE is not recommended to be caught, however the NPE is in a method whose return value is a boolean based on the variable where the NPE comes from.
Code is something like this:
public static boolean isStale() {
return a.get(); //a==null causing NPE
}
In my case, I don't really know what to return without the info of a.
What should I do? What kind of exception should I throw, if any?
Edit:
1. returning true or false will be inaccurate because the result really depends on the info inside a.
a is acctually from a service call client.getA()
There is no reason why you should prevent your code from throwing exceptions. Just consider your case : you say yourself that the behaviour of your method is not defined in the case a == null, so why should you handle it ? It will only lead to weird behaviours and your users might be surprised that their code failed or produce unexpected results somewhere whereas their calls into your API went fine.
Exceptions are specially designed to address this kind of things, so make good use of it. You can either throw a new, custom exception to add some API-specific semantic, or let the NPE be propagated to the caller.
For example :
public static boolean isStale() {
if (a == null) throw new IllegalStateException("a should not be null");
return a.get();
}
However, it is more likely that you should do that in a constructor (because I assume a is an attribute). In a constructor, I would opt for IllegalArgumentException.
First you need to ask yourself: Is it normal for a to ever be null?
If yes, then throwing an exception is rarely a good idea. Exceptions should really only be thrown when something unexpected occurs. It then really is up to you to decide what this means for your program. Does it make sense to return some default value in this case?
return a == null ? false : a.get(); // return false as a default value?
If no (more likely):
... then ask the following question: Why am I getting a null value?
If it's because you coded a bug: then you don't need to do anything. Just let it throw a NullPointerException. There really is no point in catching the exception and pretending everything is alright, if clearly, a basic invariant in your program has been broken. Better to let it throw the exception early and focus your energies on understanding and fixing the bug asap. Trying to handle the exception will only cause your program to fail at some other more unexpected point in time, and will become that much harder to debug.
If, on the other hand, it's because of some external entity feeding you bad data over which you really have no control: then this could be a good case for throwing a custom exception that can be used to provide a more meaningful error message to either the user or the developer. But even in this case, it's probably a better idea to have a validated for a null value more "upstream" and have it throw an exception as early as possible. It doesn't feel like it should be part of the isStale() method's contract to worry about the correctness of a's value.
Interesting reading, geared towards C#, but the principles apply just as well to Java: Vexing exceptions.
This depends on what isStale() determines. You can try/catch this method and catch the NullPointerException. I don't believe this violates best practices if you really have no way to handle a being null. You could also instantiate a new a if a is null, or throw your own Exception.
There's no need to throw any Exception just make sure a isn't null before using it, use a simple conditional statement:
public static boolean isStale() {
a!=null ? return a.get() : return false;
}
In the case where returning false will be irrelevant, you can just change the return type of your method to String and return a warning or any other significant message :
public static String isStale() {
a!=null ? return a.get().toString() : return "NULL";
}
Take a look at this: Best approach to converting Boolean object to string in java

Return a value AND throw an exception?

I'm working with an API that claims to return true if it succeeds, and false if it fails. But, it also claims to throw different exceptions if it fails. How can it return false and throw an exception?
It's not possible to both throw an exception and return a value from a single function call.
Perhaps it does something like returning false if there's an error, but throwing an exception if the input is invalid.
edit: PaulPRO posted a (now-deleted) answer pointing out that it is technically possible to cause an exception to be thrown in a different thread, while returning a value in the current one. I thought this was worth noting, even if it's not something you should ever see.
You can throw an exception that has a (in this case boolean) value:
public class ValueException extends Exception {
final boolean value;
public ValueException(boolean value, String message) {
super(message);
this.value = value;
}
public boolean getValue() {
return value;
}
}
While it is possible to write your code in such a way that an exception AND a value can be derived from a function call (see the above posts), it should NEVER be done in proper coding.
I would love to a see a link to the documentation on this API. API's should place a priority on clarity. Throwing an exception and returning a value leaves the question of whether the value that was returned is safe to use or if it is invalid.
Remember, try/catch blocks are the OTHER method of handling exceptions. They don't pass the exception to the calling method, but handle it internally in a way that the developer deems appropriate.
If, for debugging purposes, you need to see the resulting value in the case of an exception, then Bohemian's idea works well.
Although this question is old, I found a library that does so. It is to note that this uncommon and might be misleading to add values to the error object.
This library wraps that behavior under the hood so you don't need to do it yourself and cause confusion for others working on your code:
https://github.com/bacloud23/eager_return_js
It is in JavaScript but the same implementation can be done in Java.

What is a good "Error Checking" Pattern (Java)?

I'll explain what I mean by input error checking.
Say you have a function doSomething(x).
If the function completes successfully doSomething does something and returns nothing. However, if there are errors I'd like to be notified. That is what I mean by error checking.
I'm looking for, in general, the best way to check for errors. I've thought of the following solutions, each with a potential problem.
Flag error checking. If doSomething(x) completes successfully return null. Otherwise, it returns a boolean or an error string. Problem: Side effects.
Throwing an exception. Throw an exception if doSomething(x) encounters an error. Problem: If you are performing error checking for parameters only, throwing an IllegalArgumentExceptionseems inappropriate.
Validating input prior to function call. If the error checking is only meant for the parameters of the function, then you can call a validator function before calling the doSomething(x) function. Problem: What if a client of the class forgets to call the validator function before calling doSomething(x)?
I often encounter this problem and any help or a point in the right direction would be much appreciated.
Throw an exception is the best way.
If you are performing error checking for parameters only, throwing an
IllegalArgumentException seems inappropriate.
Why? That's the purpose of this Exception.
Flag error checking
This is appropriate in some cases, depending on what you mean by an "error".
An example from the API: If you try to add an object to a Set, which already contains another object which equals the new object, the add method sort of "fails" and indicates this by returning false. (Note that we're on a level at which it's technically not even an "error"!)
2.Throwing an exception
This is the default option.
Question is now, should you go for a checked exception (which you need a throws declaration or try/catch clauses) or an unchecked exception (an exception that extends RuntimeException). There are a few rules of thumbs here.
From Java Practices -> Checked versus unchecked exceptions:
Unchecked exceptions: Represent defects in the program (bugs) - often invalid arguments passed to a non-private method.
Checked exceptions: Represent invalid conditions in areas outside the immediate control of the program (invalid user input, database problems, network outages, absent files)
Note that IllegalArgumentException is an unchecked exception, perfectly suitable for throwing when arguments are not as they should be.
If you want to throw a checked exception, you could A) roll your own by extending Exception, B) use some existing checked exception or C) "chain" a runtime exception in, for instance, an IOException: throw new IOException(new IllegalArgumentException("reason goes here..."));
3.Validating input prior to function call
Relying on the fact that the client should have sanitized / checked his arguments before the call seems like a bad idea to me.
Your second suggestion ("Throwing an exception") is the best choice. The other two options rely on the invoker either doing something before ("Validating input prior to function call") or after ("Flag error checking") the call to the method. Either way, the extra task is not mandated by the compiler so someone invoking the function isn't forced to call the "extra thing" so problems are not spotted till run-time.
As for "Throwing an Exception" and your suggested 'problem', well the answer is throw appropriate exception types for the code. If the input parameters are invalid, then throw an InvalidArgumentException (since that's the appropriate error). If the exception is for functionality (e.g. cannot open network connection), use another exception type or create your own.
I agree with throwing exceptions. I want to add another option that combines #2 and #3 - the proxy pattern. That way your code stays fairly cohesive - validation in one place and business logic in another. This makes sense if you have a large set of calls that need to be validated.
Create a proxy to handle validation. Have it delegate all calls to the actual implementation of your business logic interface after it validates, otherwise it can throw exceptions if something does not validate.
I decide which method to use usually on the type of interface.
User interface (GUI): I validate before calling business methods, because the user wants to know what was wrong.
On technical interfaces between components or systems, the interface should have been tested and work properly in this case I throw exceptions.
Exceptions is the way to go. Your stated problem with exceptions can be mitigated by the proper implementation of exception throwing / handling. Use exceptions to your advantage by validating parameters at the lowest level that you need them and throwing an exception if the validation fails. This allows you to avoid redundantly checking for validity at multiple levels in the call stack. Throw the exception at the bottom and let the stack unroll to the appropriate place for handling the error.
The method you choose depends on the situation, and they are not mutually exclusive so you can mix them all in the same solution (although whether that's a good idea really depends on your situation).
Choose this method if you want a very simple method for handling errors. This method might be OK for situations where the calling function can accept any value the called function returns. There might be situations where business logic dictates this as an OK choice, such as returning a specific message string when a resource cannot be properly located, or a server does not respond. Generally, I don't use this or see this technique in Java very much, as exceptions are a better mechanism for error handling.
Throw an exception when your function runs into un defined behaviour. If you have a math function that can only operate on positive integers and someone passes -1, you should thrown an InvalidArguementException. If your function is given the ID of a product in a database, but the product cannot be found by a query, you could throw a custom ProductNotFound exception.
Validating input is a good idea, I would say it should be done by the called function, rather than the caller - unless the caller can avoid an exception from the callee by validating the input before passing it. If you work in a language that supports Design By Contract, validating input would be done as the function's precondition.
I usually use #2 and #3. I haven't written code with error flags for a while. The exception to that might be a function that returned an enum, where one possible value indicated an error code. That was driven more by a business rule than anything else.
And generally, try to keep it simple.
Throw a custom checked exception.
doSomething(WithX x ) throws BusinessRuleViolatedException
Input validation is surprisingly complicated and all three of the suggested approaches in the original post are needed and sometimes more. Exceptions are appropriate when input is outside the bounds of business logic, if it is corrupt or cannot be read for example.
Flag checking quickly becomes an anti-pattern if you have more than one or two flags to check, and can be replaced with a slightly specialized version of the visitor pattern. I do not know the exact name of this specific pattern, but I'll informally call it the "validator list pattern" and will describe it in more detail below.
Checking input early and failing fast is usually good, but not always possible. Often there is a lot of input validation, all input received from outside of your control should be treated as hostile and requires validation. Good program design and architecture will help make it clear when exactly this needs to happen.
'The Validator List Pattern'
As an example, let's first describe in code the "Validation Flag" anti-pattern, and then we'll transform it to the "validation list" pattern.
public Optional<String> checkForErrorsUsingFlags(
ObjectToCheck objToCheck ) {
// the small series of checks and if statements represent the
// anti-pattern. Hard to test and many other problems crop up.
String errMsg = checkForError1( objToCheck );
if(errMsg != null ) {
return Optional.of(errMsg);
}
errMsg = checkForError2( objToCheck );
if(errMsg != null ) {
return Optional.of(errMsg);
}
return Optional.empty();
}
/**** client usage ****/
ObjectToCheck obj = doSomethingToReadInput(obj);
Optional<String> error = checkForErrors( obj);
if (error.isPresent()) {
// invalid input, throw object away and request input again
} else {
// do stuff, we have a valid input
}
To fix, start by creating a common interface that will represent a single validator. Then each check is converted to a validator instance. Finally we create a list of validators and pass it to the validator code.
/** The common validator interface each validator will use */
private interface MyValidator {
public boolean isValid(ObjectToCheck obj);
public String getErrorMessage(ObjectToCheck obj);
}
// this method should look familiar to the above, now we
// have a list of validators as an additional parameter
public Optional<String> checkForErrors( ObjectToCheck objToCheck,
List<MyValidator> validators ) {
for(MyValidator validator : validators ) {
if (!validator.isValid(objToCheck)) {
String errMsg = validator.getErrorMessage(objToCheck);
return Optional.of(errMsg);
}
}
return Optional.empty();
}
/****** client usage *****/
// now in this pattern, the client controls when the validators
// are created, and which ones are used.
MyValidator validator1 = new MyValidator() {
#Override
public boolean isValid(ObjectToCheck obj) {
return checkForError1( objToCheck ) != null;
}
#Override
public boolean getErrorMessage(ObjectToCheck obj) {
return checkForError1( objToCheck );
}
}
// note: above we call checkForError1 twice, not optimal.
// typical in real examples this can be avoided,
// and the error message generation logic split from the detection
// logic often simplifies things.
MyValidator validator2 = new MyValidator() { ... }
List<MyValidator> validators =
ImmutableList.of( validator1, validator2);
Optional<String> error = checkForErrors(objToCheck, validators);
if (error.isPresent()) {
// invalid input, throw object away and request input again
} else {
// do stuff, we have a valid input
}
Now to test, create a series of mock validators and check that each one has their validate called. You can stub validator results and ensure the correct behavior is taken. Then you also have access to each validator individually so you can test them one by one on their own.
Cheers - hope that helps, happy coding.

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.

Throwing exceptions to control flow - code smell? [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 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!

Categories