background

We have a function on the APP, which needs to obtain the user’s current location. When the user turns off the GPS and fails to obtain the user’s location, a bug will be triggered. The popup content is as follows.

Problem analysis

The direct cause of this problem is that the mobile terminal cannot get the value, so the variable is not assigned, so the “undefined” is passed to the back end. The Integer defined by the value at the back end fails to convert, and an error is reported.

The underlying reason was that there was a problem with the exception handling mechanism, so the back end and the front end started fighting

Front end view: The back end code is too weak and should be fault-tolerant even if the front end passes wrong. In addition, there are versions of the APP. Even if the APP is hotfix, users may not upgrade. Users of the previous version will still have problems.

Back-end view: There is no exception pocket mechanism on the front end, and users should not see any such program exceptions. For exceptions with custom requirements, report specific exceptions and no general exceptions should be displayed, such as pop-ups of “service unavailable”. In addition, this kind of HTTP request level constraint, the front end does not comply with the constraint, but also to blame me. I intercepted the backend framework level for you, not to the business code.

What both sides said was so reasonable that neither side could convince the other. But there was agreement on the goal: never let users see this type of popover exception.

Since we can’t convince each other, we can only analyze the problem from a deeper perspective and see a more reasonable solution

General exception handling

HTTP usually has errors

  • 4 Start: The parameters of the client are abnormal, and debug information needs to be provided by the backend. In theory, it should only appear in the syndication, but not necessarily in practice.
  • 5 Start: An error occurs on the server, and the client provides unified exception handling
  • Start with 2: The service is abnormal. If there is a UI requirement, the backend returns a code and the front-end displays the UI according to the code. If there is no UI requirement, the front end simply displays the error message returned by the back end.

To unify exception handling, companies typically use apis that return a set of data formats,

{
    "error_code": "xx", // code code, 1 indicates normal, other indicates abnormal."error_msg": "xx"MSG, error message"data": "xx"// Normal data}Copy the code

So do we, and all the data starting with 4 are uniformly processed into this uniform data format.

So the logic of the front end handling exceptions

The problem this time is going to be the branch of 2.

The problem is that the back end abstracts the exception model, and the client parameters have problems. The back end needs to provide debugging information, not to show the error information to the user.

There are actually three types of exceptions on the server

  • Abnormal client parameters (front-end needs debug messages and error MSG messages)
  • Service exceptions that need to be known to the user and displayed by the front-end according to the code (the front-end needs the code)
  • A generic server exception wrapped as a message to the front end. (The front end requires error MSG information)

solution

After analyzing the problem clearly, there is a method of understanding.

Solution 1: Separate error messages from debug messages, and add a field to the returned API unified format. Debug_msg is for developers,error_msg is for users

Solution 2: Define several enumeration codes. As a development contract

code error_msg Parameter Error Meaning
010000 System error [010000] Request method not supported
010001 System error [010001] Missing path parameter
010002 System error [010002] Required request parameters are missing
010003 System error [010003] Type mismatch
010004 System error [010004] Request body exception
010005 System error [010005] // Error in body or param
010006 System error [010006] Parameter binding exception (form)

Solution 1 has a clear definition, but the cost of network transmission is high because of the overhead of a field in this corner case. In addition, the front-end also needs to cooperate with the change, the change cost is relatively large.

Solution 2 is compatible with the current implementation and does not need to change the front end, but it is not very friendly for the error notification of the client parameters. It cannot display the specific parameter error on the front end. Log only.

Discuss with the front end and make sure you understand method 2.

conclusion

So this problem, the final solution

  • The front end can not obtain the positioning, willundefinedThis variable is assigned
  • The back end has changed the exception handling mechanism for the mobile service
@RestControllerAdvice
public class ApiStandardException {
    private static final String ERROR_MSG = "System error";
 
    @ExceptionHandler(value = Exception.class)
    public ResponseEntity<Result> handle(final Exception ex, final WebRequest request)
            throws Exception {

        try {
            if(ex instanceof HttpRequestMethodNotSupportedException) {/ / request method does not support the warn ("Request method is not supported");
                throw new BusinessException(WebRequestErrorEnum.METHOD_ERR.getCode(), ERROR_MSG);
            } else if (ex instanceof MissingPathVariableException) {
                LOG.warn("MISSING_PATHVAR"+ ex.getMessage()); / / lack of path parameter throw new BusinessException (WebRequestErrorEnum. MISSING_PARAM. GetCode (), ERROR_MSG); }else if(ex instanceof MissingServletRequestParameterException) {/ / lack of must request parameters} / / omit other exception handlingCopy the code

Pay attention to [Abbot’s Temple], receive the update of the article as soon as possible, and start the road of technical practice together with the abbot