Java exception capture in the era of microservices

1. Try not to use e.printStackTrace(), but use log printing.


​Counterexample:​

try{
  // do what you want  
}catch(Exception e){
  e.printStackTrace();
}

Positive example:​

try{   // do what you want   }catch(Exception e){   log.info("Your program has an exception,{}",e); }





Reason:​


The stack log printed by printStackTrace() is interleaved with the business code log, so it is not convenient to check the exception log.
The string generated by the e.printStackTrace() statement records the stack information. If the information is too long and the memory block where the string constant pool is located has no space, that is, the memory is full, then the user's request will be stuck~

2. The exception is caught, but the specific exception is not printed out, so the problem cannot be better located


​Counterexample:​

try{   // do what you want   }catch(Exception e){   log.info("Your program has an exception"); }




 

​Positive example:​

try{   // do what you want   }catch(Exception e){   log.info("Your program has an exception, {}",e); }



Reason:

In the counter example, the exception is not released, and it will be difficult to troubleshoot the problem at that time. Is it a SQl error, an IO exception, or something else? So the exception should be printed to the log~

3. Don’t use an Exception to catch all possible
exceptions

Counter example:​

public void test(){     try{         //...code call that throws IOException         //...code call that throws SQLException     }catch(Exception e){         //Use the base class Exception to catch all possible exceptions, if there are multiple levels All captures like this will lose the effective information of the original exception         log.info(“Exception in test,exception:{}”, e);     } }









Positive example:​

public void test(){     try{         //...code call that throws IOException         //...code call that throws SQLException     } catch(IOException e){         //only catch IOException         log.info("IOException in test, exception:{ }", e);     }catch(SQLException e){         //Only catch SQLException         log.info("SQLException in test, exception:{}", e);     } }











 

reason:

Use the base class Exception to capture all possible exceptions. If multiple levels are caught in this way, the effective information of the original exception will be lost.

4. Remember to use finally to close the stream resource or use try-with-resource directly

​Counterexample:​

FileInputStream fdIn = null;
try {     fdIn = new FileInputStream(new File("/jay.txt"));     //close stream resource here? Is there any problem? What if an exception occurs?     fdIn.close(); } catch (FileNotFoundException e) {     log. error(e); } catch (IOException e) {     log. error(e); }








Positive example 1:

You need to use finally to close the stream resource, as follows

FileInputStream fdIn = null;
try {
    fdIn = new FileInputStream(new File("/jay.txt"));
} catch (FileNotFoundException e) {
    log.error(e);
} catch (IOException e) {
    log.error(e);
}finally {
    try {
        if (fdIn != null) {
            fdIn.close();
        }
    } catch (IOException e) {
        log.error(e);
    }
}


Positive example 2:

Of course, you can also use the new feature try-with-resource of JDK7, which is a new feature provided by Java7, which is used for automatic resource management.


Resources are objects that must be closed when the program is done with them.
try-with-resources guarantees that each declared resource will be closed at the end of the statement.
What kind of objects can be used as resources? As long as the object that implements the java.lang.AutoCloseable interface or java.io.Closeable interface is OK.

try (FileInputStream inputStream = new FileInputStream(new File("jay.txt")) {
    // use resources   
} catch (FileNotFoundException e) {
    log.error(e);
} catch (IOException e) {
    log.error(e);
}


Reason:

If you do not use finally or try-with-resource, when an exception occurs in the program and the IO resource flow is not closed, then this IO resource will always be occupied by it, so that others will have no way to use it, which will cause a waste of resources.


5. The caught exception and the thrown exception must be an exact match, or the caught exception is the parent class of the thrown exception

​Counterexample:​

//BizException is a subclass of Exception
public class BizException extends Exception {}
//throws parent class Exception
public static void test() throws Exception {}


try {     test(); //Compilation error } catch (BizException e) { //Catch exception subclasses cannot match     log.error(e); }




​Positive example:​

//Throw subclass Exception
public static void test() throws BizException {}


try {
    test();
} catch (Exception e) {
    log.error(e);
}
 

6. The caught exception cannot be ignored, at least log it


​Counterexample:​

public static void testIgnoreException() throws Exception {     try {                // do things     } catch (Exception e) { // generally there will be no such exception


    }
}


​Positive example:​

public static void testIgnoreException() {     try {         // do things     } catch (Exception e) { // generally there will be no such exception         log.error("This exception should not appear here,{}",e);      } }






Reason:​

Although an exception that will not happen under normal circumstances, if you catch it, don't ignore it, at least make a log~

7. Pay attention to the infection of exceptions on your code hierarchy (early detection and early processing)


​Counterexample:​

public UserInfo queryUserInfoByUserId(Long userid) throw SQLException {     //Query the database according to the user Id }


 

​Positive example:​

public UserInfo queryUserInfoByUserId(Long userid) {     try{         //Query the database according to the user Id     }catch(SQLException e){         log.error("The query database is abnormal, {}", e);     }finally{         //Close the connection and clean up resource     } }









Reason:

Our projects generally divide the code into different hierarchical structures such as Action, Service, Dao, etc. If you are dealing with an exception at the DAO layer, handle it as soon as possible. If SQLException is thrown upwards, the upper layer code still needs to be handled by try catch. It pollutes your code~


8. Customize the package exception, do not discard the original exception information Throwable cause


We often want to throw another exception after catching one exception, and we want to save the information of the original exception, which is called exception chain. The company's framework provides unified exception handling and uses the exception chain. We customize the package exception and don't discard the original exception information, otherwise troubleshooting will be a headache.

​Counterexample:​

public class TestChainException {     public void readFile() throws MyException{         try {             InputStream is = new FileInputStream("jay.txt");             Scanner in = new Scanner(is);             while (in.hasNext()) {                 System.out.println (in.next());             }         } catch (FileNotFoundException e) {             //e save exception information             throw new MyException("Where is the file");         }     }     public void invokeReadFile() throws MyException{         try {             readFile();         } catch (MyException e) {             //e save exception information

















            throw new MyException("File not found");
        }
    }
    public static void main(String[] args) {         TestChainException t = new TestChainException();         try {             t.invokeReadFile();         } catch (MyException e) {             e. printStackTrace();         }     } } //MyException constructor public MyException(String message) {         super(message);     } The running results are as follows, there is no Throwable cause, so it is difficult to troubleshoot what is abnormal













Positive example:​

public class TestChainException {     public void readFile() throws MyException{         try {             InputStream is = new FileInputStream("jay.txt");             Scanner in = new Scanner(is);             while (in.hasNext()) {                 System.out.println (in.next());             }         } catch (FileNotFoundException e) {             //e save exception information             throw new MyException("Where is the file", e);         }     }     public void invokeReadFile() throws MyException{         try {             readFile( );         } catch (MyException e) {             //e save exception information

















            throw new MyException("File not found", e);
        }
    }
    public static void main(String[] args) {         TestChainException t = new TestChainException();         try {             t.invokeReadFile();         } catch (MyException e) {             e.printStackTrace();         }     } } //MyException constructor public MyException(String message, Throwable cause) {         super(message, cause);     }












 


Nine, run-time exception RuntimeException, should not be handled by catch, but pre-checked first, such as: NullPointerException handling


​Counterexample:​

try {
  obj.method() 
} catch (NullPointerException e) {
...
}

​正例:​

if (obj != null){
   ...
 


10. Pay attention to the order of exception matching, and give priority to catching specific exceptions


Pay attention to the matching order of exceptions, because only the first catch block that matches an exception will be executed. If you want to see that it is a NumberFormatException, throw a NumberFormatException, and if it is an IllegalArgumentException, throw an IllegalArgumentException.

​Counterexample:​

try {
    doSomething("test exception");
} catch (IllegalArgumentException e) {       
    log.error(e);
} catch (NumberFormatException e) {
    log.error(e);
}

Positive example:​

try {
    doSomething("test exception");
} catch (NumberFormatException e) {       
    log.error(e);
} catch (IllegalArgumentException e) {
    log.error(e);
}
 

reason:

Because NumberFormatException is a subclass of IllegalArgumentException, in the counter example, no matter which exception it is, it will match IllegalArgumentException, and it will not be executed further, so I don’t know whether it is NumberFormatException. So you need to give priority to catching specific exceptions, put NumberFormatException first~
 

Guess you like

Origin blog.csdn.net/swebin/article/details/132437607