Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

There are plenty of wisdom out on the internet regarding exceptions and handling.  Here is some general anti-patterns and, on the bottom of that page, there are resources to other guidelines.  There are a few that I like to single out as important.

  1. Don't just catch exception. Always catch the specific exception first.
    Code Block
    try {
        code...;
    } catch (Exception specific to your code) {
        Specific exception handling and logging;
    } catch (Exception e) {
        s_logger.warn("Caught unexpected exception", e);
        exception handling code.
    }
    
  2. Don't mask the exception that caused the problem by leaving it out of the new exception that was thrown.
  3. Code Block
    try {
        code...;
    } catch (XenAPIException e) {
        // Do either this: s_logger.warn("Caught a xen api exception", e);
        // or throw new CloudRuntimeException("Caught a xen api exception", e);
        throw new CloudRuntimeException("Got a xen api exception"); // Don't ever do JUST this.
    }
    
  4. Code Block
    public void irresponsibleMethod() throws Exception;
    public void responsibleMethod() throws XenAPIException;
    public void runtimeExceptMethod(); // throws CloudRuntimeException that's not suppose to be logged until entry point.
    public void innocentCaller() {
    try
    { 
        irresponsibleMethod(); 
        responsibleMethod(); 
        runtimeExceptionMethod(); 
    } catch(Exception e) { 
        s_logger.warn("Unable to execute", e); 
        throw new CloudRuntimeException("Unable to execute", e); 
        // What's wrong here? 
        // 1. If the error was thrown from responsibleMethod, the caller now forgot to do special handling for XenAPIException. 
        // 2. If the error was thrown from runtimeExceptionMethod, the caller now log it once here, and will log again at entry point. 
    }
    
  5. Don't ever throw Exception itself.  If you need a checked Exception, either find one that fits your needs or create one yourself.  If what you run into shouldn't be possible or is due to programmer mistake, then throw CloudRuntimeException.  To decide if you need a CloudRuntimeException, ask yourself this, is this similar to hitting a null pointer?  NullPointerException is a runtime exception because if the caller wanted to handle the pointer being null situation, they would have handled it before calling.  Checked exceptions should be thrown if and only if the caller has a reasonable chance of handling the exception other than log and report error.  Prefer CloudRuntimeException unless you have a good reason to throw a checked exception.  Note the words "programmer mistake" here.  User errors should be handled properly.
  6. Code Block
    try {
        some code;
    } catch(XenAPIException e) { // catch generic error here.
        s_logger.debug("There's an exception. Rolling back code: " + e.getMessage());
        ...rollback some code;
        throw e; // note there's no "new" here.
    }
    
  7. Code Block
    for (Task task : taskList) {
        try { 
           process task; 
        } catch (Exception e) {
            ...handle exception and continue 
        }
    }
    

...