简体   繁体   中英

Handling Multiple Exceptions within a Method

I am currently working on the maintenance of a piece of code that is a little bit "Exception Happy." Basically, ever method or anything throws Exception. I'm going to work to take care of that, but, in the meantime, I am wondering what is the best way to handle individual exceptions within a smaller block of code, such as a method. Is it better to do something like this:

public void aMethod()
  try {
    //Lots of code in here.  Many lines.
  } catch(Exception e) {
    // TODO - Handle All Exceptions, but fairly generically
  }
}

Or something like this:

public void bMethod() {
  try {
    // One line of code.
  } catch(Exception e) {
    // TODO - Handle a specific Exception (may even involve rethrowing it with more information)
  }

  // More code.

  try {
    // Another line of code.
  } catch(Exception e) {
    // TODO - Handle another specific exception.
  }
}

I realize this is a pretty basic question, but after looking at hundreds of methods with Exceptions coming out of every one, I'm starting to wonder how best to handle all of them and what a best practice may be here.

First off, you should only put code in try/catch blocks that is exception worthy. For instance, having an unexpected value is not necessarily an exception, but trying to read from a file that doesn't exist is.

To answer your main question, you should put the exceptionable code in the same try {} block and catch specific questions in order of granularity in multiple catch blocks after the main try.

//Regular code that doesn't need to be covered by a try/catch block

try {

  //critical code only

} catch (NullPointerException npe) {
  //Code
} catch (RandomException re) {
  //code
} catch (Exception e) {
  //code
}

The answer to your question is: it depends.

  • if the code in the try block is coherent where it makes no sense to proceed in the event of an error, the first approach is best
  • if the code is taking seperate steps that are relatively unrelated (parsing numbers for instance) and can be recovered without aborting the rest of the method the seconds appraoch makes sense

A general remark on the code you inherited; it sounds like exceptions are abused to pass state around, I would refactor so that exceptions are caught at the spot where they can be handled and introduce return values or attributes to handle the state.

your bMethod isn't very useful illustration. Try to reprase it. Anyway, you have two options:

  1. catch exceptions and log them.
  2. catch exceptions and throw new RuntimeException(ex) (rethrow a runtime exception, setting the original as a cause)

Also, you will need to differentiate between exceptions. If your system has many custom exceptions, they are probably defined for a reason, and specific behaviour is expected when one of them is thrown.

If the try/catch block isn't adding useful information, just allow the method to throw the exception and have it handled where the caller can sensibly do something with the exception. This could cut down the number of try/catch significantly (by an order of magnitude).

BTW a trick for rethrowing any exception is.

try {
   // do something
} catch (Throwable t) {
   Thread.currentThread().stop(t); // rethrow any exception.
}

In addition to the suggestions already made you may also want to consider extracting try/catch blocks from the "meat" of the function.

public void delete(Page page) {
    try {
        deletePageAndAllReferences(page);
    }
    catch (Exception e) {
        logError(e);
    }
}

private void deletePageAndAllReferences(Page page) throws Exception {
    deletePage(page);
    registry.deleteReference(page.name);
    configKeys.deleteKey(page.name.makeKey());
}

private void logError(Exception e) {
    logger.log(e.getMessage());
}

This lets you focus your attention on the function you are really interested in without the exception handling getting in your way.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM