This is the 31st day of my participation in the August More Text Challenge
Java theory has been explained in Java Exception Handling. How does the theory guide the implementation
Now popular article SpringBoot how to gracefully handle exceptions, landing is really convenient, using AOP unified processing exceptions, but only processing the API level of exceptions
There are two ways to throw an exception in an application:
- Exception with ErrorCode
- Specify the type of exception
For the Controller layer, which is also user-oriented, error code is required, so the first method is used
The front end provides hints for better user experience through mapping. In many projects, hints are directly spliced at the Controller layer and displayed directly at the front end
So you usually define an interface ErrorCode
interface ErrorCode {
String getErrorCode();
String getMessage();
}
Copy the code
The specific implementation can be enum
@getter enum ApiErrorCode implements ErrorCode {USER_NOT_FOUND("10000"," user does not exist "); private String errorCode; private String message; }Copy the code
Define another unified exception
public class ApiException extends RuntimeException {
public ApiException(ErrorCode errorCode) {
}
}
Copy the code
When AOP intercepts, simply intercept this exception
Exceptions at the API level can be handled this way, but what about at the business level? Most of the time, there is a lack of design. As mentioned in the previous article, exceptions are syntactically simple, but it is very difficult to design a good one
Most projects use API Exceptions directly as Business Exceptions
For a good business interface, the second approach should be fine-grained exceptions
User login(String username, String password) throws UserNotFoundException, PasswordNotMatchException;
Copy the code
Checked exceptions are much better than error return codes (used in many older languages). Sooner or later (perhaps soon), people won’t be able to check for an error return value; Using compilers to implement proper error handling is a good thing. Like parameters and return values, such checked exceptions are an integral part of an object’s API
Such interfaces are richer and more object-oriented, but they also cause problems for the client side, as discussed in the previous article
Use checked exceptions for recoverable cases and run time exceptions for program errors
In most projects, when the business layer throws an exception, is it usually “recoverable”? Most of the time also need the user manual intervention, the system can’t recover, such as UserNotFoundException PasswordNotMatchException system how to deal with, but still have to give the user to enter the user name and password
If you call the service method at the Controller layer, that’s all you have to do
Response login(String username,String password) { try { userService.login(username,password); }catch(UserNotFoundException ue) { throw new ApiException(ApiErrorCode.USER_NOT_FOUND); }catch(PasswordNotMatchException pe){ throw new ApiException(ApiErrorCode.Password_Not_Match); }}Copy the code
So this is theoretical, how many advantages does it bring? Aren’t those the ones where checked Exceptions get grumbled
We can also define a business exception as a Runtime Exception. This will reduce the pressure on the client. We can handle it if we want to, or we can handle it in the interceptor
However, the runtime exception is thrown, reducing the pressure on the client, but also causing confusion with unclear interfaces
One of the biggest risks of an unchecked exception is that it is not self-documented in the way that checked exceptions are. Unless the API’s creator explicitly documents the exception to be thrown, there is no way for callers to know what exception to be caught in their code
In summary, again, exception syntax is simple, but designing exceptions is difficult; Nowadays, with the rapid development of technology, greater convenience can be achieved through technical means, but design can not be ignored only by technical means. The code without design is not good code, which can be chosen, but can not be completely abandoned