简体   繁体   中英

Handling recoverable and unrecoverable exceptions

Hopefully I can explain this clearly. If I have a main method with lots of steps that can generate different exceptions, some fatal, some not, do I have to catch the "recoverable" ones separately? It seems like that would result in potentially a lot of try/catch blocks, like so:

public static void main (String[] args) {
    try {
        //...
        for (int i=0;someArray.length;i++) {
            try{
                System.out.println("I = " + i);
                doSometing(i);
            } catch (RecoverableException e) {
                //recover, continue, whatever
                //log warning
                                    //keep 
            }
        }//end for loop

        try {
            doSomethingElse();
        } catch (AnotherRecoverableException e) {
            //not fatal, keep on chugging
        }

        //...

        //do more stuff that can throw unrecoverable exceptions
    } catch (UnrecoverableException e) {
        System.out.println("I can't handle this, it's too much!");
        e.printStackTrace();
    }
}

Is there a better way to do this?

If you are using Java 7 then you can club exceptions in the catch block using pipe as separator. This will reduce your number of catch blocks. But you need to decide how you want to handle them by putting appropriate code in the catch block.

In Java 7, you can do this:

try
{
...
}
catch(Exception1 | Exception2 | Exception3 e)
{
  //Handle
}
catch(Exception4 | Exception5 | Exception6 e)
{
   //Handle differently
}

My patterns are to let exceptions propagate when they would represent programming bugs and handle them as closely to the "problem" when you can handle them.

The problem is that many potential Programming bugs throw checked exceptions which is really bad (Checked exceptions are kind of a failed experement, the newer languages have gotten rid of them).

So:

  • Handle checked and unchecked exceptions that you can deal with immediately.
  • If you don't know how to handle a checked exception rethrow it as an unchecked exception.
  • any "top level" loop like in main or a thread should be surrounded by a try/catch/log of "Exception" to ensure that any exception that bubbles up doesn't kill the thread (but log it loudly because it represents an unknown programming bug!)
  • Any critical loop that should continue regardless of exceptions should have a try/catch/log of "Exception" inside the loop construct so it will continue.
  • Catch exception, not throwable at this high level. Throwable includes unrecoverable exceptions that you probably never want to catch.
  • If you really must throw an exception you think you want the caller to catch (try to avoid this--It means you are using Exceptions as code flow!), throw an unchecked exception but document it and have the method "throw" the unchecked exception (it doesn't HAVE to be handled, but this acts as additional documentation/hint).

    Just as a background for why I dislike checked exceptions so--it makes code like this happeen:

    \ntry { \n   Thread.sleep(1000); \n} catch(InterruptedException e) {} \n

    This can hide some INCREDABLY annoying to find program-flow related bugs. In this case it simply means you might have some thread-control issues, but in others it can mean your code-flow "Magically" vanishes mid-method with no indication whatsoever (because an exception was picked up by a higher level try/catch).

  • You can use. defaultUncaughtExceptionHandler , but it only triggers if the Thread doesn't have a uncaughtExceptionHandler set.

    For java versions other than 7, a cleaner approach is to handle exceptions in called methods. This makes code readable as shown below:

    doSomething(int i){
     //code
    try{
     //code
    }catch(Exception1 e1){
     //handle
    }
    catch(Exception2 e2){
    //handle
    }
    }
    
    doSomethingElse(){
     //code
     try{
      }catch(Exception1 e1){
     //handle
      }
       catch(Exception2 e2){
        //handle
        }
      }
    
     public static void main (String[] args) {
        for (int i=0;someArray.length;i++) {
         doSometing(i);
        }//end for loop
    
        doSomethingElse();
        }
    

    I do not recommend using generic Exception to catch all errors in one block. This makes difficult to know specific exceptions and prevents specific handling of them.

    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