Exception Handling Best Practices

Source: Internet
Author: User
Tags i18n sql error

I. Classification of anomalies

General classification:

1, run-time exception (runtimeexception);

2. Compile-time exception (checkedexception)

Application Category:

1, interrupt (terminate) The program continues to run down;

2, interrupt the program to continue to run down, and the abnormal reasons and information sent to the upper layer.

Feature Categories:

1, can obtain the cause of the anomaly;

2, can obtain the code of exception;

3, you can get the error line number of the exception;

4, can obtain the abnormal stack information (program running track);

5, can obtain the type of exception;

...... such as

Judging classification:

1, can pre-judgment (pre-judgement), self-defined anomalies, such as our own program, in the service, when (Id==null && type==2), throw a abcexception exception;

2, non-pre-judgment, non-transparent anomalies, such as the inside of the tool library anomalies (SQLException, ibeexception) and so on.

For these different types of exceptions, their use and processing methods are not the same, see the following analysis.

Analysis of common usage scenarios for anomalies

1, Example 1: Assume that there is a web, service, DAO three layer, but in DAO beginning wrong, throw SqlException or other DAO tool library internal exception.

In this case, we usually need to log the exception information, and in the Web layer feedback to the view page, will not tell the user the underlying cause of the error, just tell the user there is an unknown exception, or probably what caused the error.

Analysis: 1) errors within the library, such as SqlException, are unpredictable for us, and we do not know when and under what circumstances errors will occur, i.e. we cannot prejudge them. 2) DAO beginning error, need to notify the upper layer, also need to log, this log is in the DAO layer record, or let the upper level decide whether to record? In fact, this is a common problem, put in the service layer or generic tool class, also has this choice: in the end is to record the log and the exception information to the upper level, or do not log logs, only the complete exception information passed to the upper layer, let the upper layer decide whether to log logs. I am in favor of the latter, generally speaking, we do not log information in the middle tier, there are exceptions directly to the outer throw thrown, very convenient for developers (this is the focus).

2, Example 2: After the example, suppose we in the service layer, made a judgment: when (password incorrect), thrown out a custom exception, the exception message is "Password Error!! ”。 In this case, we usually do not need to log, because this error is defined by ourselves, and is predictable, the role of the error message is to tell the user, rather than as a log analysis function.

Analysis: 1 Make it clear that for this type of error, we don't need to log, but we still have to return the error message to the top, and notice that we only need the error message message, no exception line number, runtime stack information, etc.

Third, Java exception processing analysis

Find the exit of the abnormal handling.

1) In general, abnormal exits are:the Web layer (action, controller) ultimately boils down to Servlets and Filter.  so, in the outermost layer of our program, such as action, there should be no more "uncaught exceptions", because we have no way of controlling them. Therefore, we have to be in the outermost, do the proper handling of the exception.  It is a special reminder that not only action, controller, or servlet or WebService, which serve as a service to the outside, are the final exits of the anomaly.  2) Custom exception exitsIn addition to the Web tier, other places can be "custom" export exceptions. For example, a utils throws an exception, I capture it inside the service, and then "fix it in place" and no longer propagate the exception. In this case, the so-called "custom anomaly Exits".  how exceptions are handleddepending on the exit classification of the exception, there are "web-layer egress exceptions" and "Custom egress exceptions".  1, the Web layer exits the exceptioncan also be categorized as follows:1) The "internationalization" (Multi-language version) of the exception message needs to be implemented. 2) "Internationalization" is not required.  a) Abnormal exits are directly oriented to the user or browser. b) Abnormal exits are intended for other systems.  for 1), the classic solution is to define all the predictable error messages (with ErrorCode and errormsg), errorcode correspond to multiple language versions of errormsg. for 2), you can simply throw out the error message without errorcode and errormsg. But it is not recommended to do so. The reasons are as follows:-The exception information can be very primitive, if stack information is used, then the stack information is not easy to display on the client. -The exception information can also be very large, such as a SQL error, only errormessage can be thousands of characters, not easy to display on the web side. -native exception information, usually for developers, may not be understandable to the user.  for a), you can directly return the specific information of the exception, if you want to support internationalization, it is also feasible. for B), it is not a good practice to return the exception information directly to other systems, since it is possible for other systems to be judged or processed for the type of exception. Therefore, it is best to return to ErrorCode and errormsg, other systems can be judged or processed according to ErrorCode.  Summary:comprehensive consideration 1) 2) a) b), a good exception handling method is: Define so predictable error messages, expressed in ErrorCode and errormsg. It is necessary to increase the language version of ErrorMsg. This requires that we not use Chinese when writing exception-handling code.    Either define the error message as ErrorCode, or describe the error message in concise English. For example,try{           .........}catch (excpetion e) {throw new MyException (errorcode.c0001, E.getmessage ());    }ortry{           ........}catch (excpetion e) {throw new Myruntimeexception ("Encode failure! N must big than 0. ");    }ortry{           ........}catch (ioexcpetion e) {throw new Exceptionwrapper (e);//Use exceptionwrapper this tool class to wrap the original error message    }these three kinds of writing, are in line with the above specifications. But the use of the scene is different. the first is that higher-level code, such as service layer, DAO layer, can be passed directly to the Web layer. So the errorcode is defined in-place. the second and third way of writing is for lower-level code, such as the lowest-level tool class.  In a customer-facing project, it is recommended to use only the first notation. The second to third type of writing is more for those service-oriented projects.  2. Custom Export ExceptionsSometimes, we do not need to notice the exception to the outside, in their own internal processing is OK. For example:try{InputStream in = Ioutils.getinputstream (FilePath);}catch (IOException e) {Log.warn (e);    }In the case of an error, logging directly is OK, and you do not need to throw the error out again.     Sometimes you can do the same thing: Public void Doparse () {    .......try{           ........}catch (ioexcpetion e) {throw new Exceptionwrapper (e);//Use exceptionwrapper this tool class to wrap the original error message    }    ......} Public void Doserviceaa () {try{doparse ();}catch (excpetion e) {throw new MyException (errorcode.c0001, E.getmessage ());    }}Public void Doserviceaa () {try{doparse ();}catch (excpetion e) {//Ignore this error    }}that is, when the error is not handled in this place, the error is thrown out, to the top to decide how to deal with the error. but this usage is still relatively small. Misuse is not recommended.

Iv. best Practices for exception handling

1, take the STC ticket control project as an example, the whole project anomaly, divided into three layers:

First layer: The most basic parent class

Basiccheckedexception (inherited from Exception)

Basicruntimeexception (inherited from RuntimeException)

(Note that the entire project, do not directly new Exception and RuntimeException)

Second floor:

Nestedcheckedexception (inherited from Basiccheckedexception)

Nestedruntimeexception (inherited from Basicruntimeexception)

Third layer: The exception type that is extended on the basis of the above 4 exception classes.

Currently there are:

Stcorigexception (Primitive exception, used in place of Exception)-inherited from Basiccheckedexception

Stcorigruntimeexception (Primitive exception, used in place of runtimeexception)-inherited from Basicruntimeexception

Stcnestedexception (nested wrapper exception, used to wrap the original exception)-inherited from Nestedcheckedexception

Stcnestedruntimeexception (nested wrapper exception, used to wrap the original exception)-inherited from Nestedruntimeexception

Stci18nexception (i18n internationalization exception, including ErrorCode and errormsg, can correspond to Chinese, English, traditional and other abnormal information)-Inherit from Basiccheckedexception

Stcnologexception (interrupts but does not log exceptions, only for interrupting program execution, but no exception information is logged outside)-inherited from Basiccheckedexception

2. Best Practice Description

To put it simple, in fact, the most used exceptions in the project are Stcnestedexception, Stci18nexception, Basiccheckedexception, and the first two for the new create exception, The latter basiccheckedexception is used to declare throws exceptions. Examples are as follows:

1  Public classUserdao {2 3Pubic User Querybyid (Long ID)throwsbasiccheckedexception {4 5         if(id<0) {6 7             Throw NewStcnestedexception ("The user with ID less than 0 does not exist!") ");8 9         }Ten  OneObject uobj =NULL; A  -         Try { -  theUobj = Getdao.query ("Select from User"); -  -}Catch(Exception e) { -  +             Throw Newstcnestedexception (e); -  +         } A  at         returnUsertools.touser (uobj); -  -     } -  -}

There are several benefits to this writing:

1) for new Stcnestedexception ("The user with ID less than 0 does not exist!") "), we don't need to record the stack and line number of the exception, just throw the error message out. This can also be replaced with an exception identified with the i18n internationalized ErrorCode code: New Stci18nexception (errorcode.usr023, id).

2) for Getdao.query ("Select from User") can throw SqlException and other exceptions, we apply the stcnestedexception, it can be intact to the original exception of the complete information (such as message, Row numbers and stacks) are saved.

Iv. the relationship between exception and log processing

Exception handling is closely related to log processing, but cannot be confused. It can be said that:

1) An exception does not have to log.

2) logging is not necessarily the time for an exception to occur.

A description of the common points of exception and log processing, for example:

1. Example (i)

DAO beginning wrong, need to notify the upper layer, also need to log, this log is in the DAO layer record, or let the upper layer (such as service layer) decide whether to record?

Analysis:

In fact, this is a common problem, put in the service layer or generic tool class, also has this choice: in the end is to record the log and the exception information to the upper level, or do not log logs, only the complete exception information passed to the upper layer, let the upper layer decide whether to log logs.

I am in favor of the latter, generally speaking, we do not log information in the middle tier, there are exceptions directly to the outer throw thrown, very convenient for developers (this is the focus).

2. Example (ii)

Because of some kind of business need, we want to log information in some Prosessor class, and also terminate program execution.

Our needs: 1) Log the error message, 2) interrupt the program to run.

Traditional practices:

1 2 3 4 5 6 try   {&NBSP; &NBSP;&NBSP;&NBSP;&NBSP; doservice ();   }&NBSP; catch (abeexception e)  { &NBSP;&NBSP;&NBSP;&NBSP; log.error (e); &NBSP;&NBSP;&NBSP;&NBSP; throw  e; }

This approach can meet the above requirements, but more than our needs. Because it throws e although the execution of the program is terminated, but it put the error message and the error stack to the outer layer, and the outer layer captures the error, it may again record the log information, which causes the log information duplication, and often the log stack information is very long, looking very laborious.

The problem is that we just want to "interrupt the program" and do not want the exception stack information to be passed out again.

At this point, the above mentioned "exception handling best practices" proposes a scenario, an exception that interrupts the execution of the program and does not log stack information--nologexception. Using Nologexception to transform the program above, it becomes:

1 2 3 4 5 6 try   {&NBSP; &NBSP;&NBSP;&NBSP;&NBSP; doservice ();   }&NBSP; catch (abeexception e)  { &NBSP;&NBSP;&NBSP;&NBSP; log.error (e); &NBSP;&NBSP;&NBSP;&NBSP; throw  new   nologexception (); }

This allows the outer layer to determine if it is nologexception, and if so the outer layer does not log. Step back, even if the outer layer does not determine whether it is nologexception, it can also log information, but there is no exception in the Nologexception information (only one error code), want to record is also not recorded.

Exception Handling Best Practices

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.