views:

57

answers:

2
catch (Exception ex)
{
    DBGlobals.Error("OHMjson.Graph.saveLastGraphName - Error: " + ex.getMessage());
    msg = "Unable to save data";
    status = false;
}

This piece of code would throw an status as false, if i encounter an error.

Instead should i thrown New expection. Is this the right way. How can i handle exception in a better way.

+4  A: 

Prefer throwing exceptions to returning error codes/status.

Returning an error code means the caller should always remember to check for it. Throwing the exception allows the calling code to make the decision of what to do (an normally the higher up the decision, the better it can be made).

Oded
+2  A: 

First, don't catch Exception. Catch a specific subclass.

Second, yes it may be that an underlying IOException, which is what this looks like, should be wrapped in an app-specific exception. You could have, for instance:

final class DBGlobalsException extends Exception
{
   Field somethingDBGlobalsSpecific;

   //where this is shorthand for chained constructors that look like Exception
   DBGlobalsException(String message, Throwable cause)
   {
     super(message,cause);
   }

   // elaborate your exception with whatever error state you want to propagate outwards
   void setField(Field ...) {}
}

And you could then

catch (IOException ex) {
   DBGlobals.Error("OHMjson.Graph.saveLastGraphName - Error: " + ex.getMessage());
   msg = "Unable to save data";
   status = false;
   DBGlobalsException dbe = new DBGlobalsException(msg,ex);
   dbe.setField(status /* or whatever */);
   throw dbe;
}

See also: Throwing Exception, Throwing new and old exceptions, Rolling your own. That's just a few, there are a bunch of great SO Q+A's on exception handling, chaining, etc. Some useful best-practices stuff outlined at WikiBooks.

Also read Oded's answer and think it through... your exception should encapsulate whatever status (error codes, flags, etc...) are required for the outer code to recover from the condition -- or it should be an unrecoverable condition (see RuntimeException).

Finally, the canonical Effective Java reference: Item 43: Throw Exceptions Appropriate to the Abstraction.

andersoj
I did not get your first point, what does it mean catch in specific subclass.
John
Why do we need to declare the class as final
John
@John: Catch a subclass of `Exception` is a best-practice -- don't catch an overly-broad class of Exceptions. Here's a good description (though in C#) http://stackoverflow.com/questions/426346/is-this-a-bad-practice-to-catch-a-non-specific-exception-such-as-system-exception
andersoj
Declare things `final` out of habit, unless you have reason to do otherwise. In the case of `Exceptions` it discourages meaningless/confusing subclassing and flatter inheritance hierarchies. I only elide the `final` keyword if I'm *planning* or *explicitly encouraging* subclassing.
andersoj
@John: Also note, `catch (Exception e)` will catch `RuntimeException` , which you generally *don't* want to do, especially in the instance you cite, where you swallow it.
andersoj
What is Field somethingDBGlobalsSpecific; Is it something like String mistake; What does the setField method do, what will the dbe finally throw to me.
John
Yeah, sure... basically, I put that in to suggest that you might have a (set of) fields in the exception instance that capture "what went wrong" at the level of abstraction of the class you're currently in, which I intuited had something to do with DBGlobals, based on your log call. It's a reminder that an `Exception` is just an object instance, and it's specifically there to pass error/non-local information out to facilitate logging, forensics, and recovery by the catching logic. It's also a nod to Oded's answer -- use the exception instance fields to pass the error code/status you need.
andersoj
The `throw dbe` will throw out an instance of `DBGlobalsException`, which is "chained" to include a reference to the caught `IOException`, and from which you can get the value of `Field` or anything else you set in there...
andersoj