API接口设计(2):全局异常处理

背景

接口异常返回信息,属于API接口规范的一部分。如何更高效的处理好异常信息,对于定位和排查问题问题,很有帮助。

全局异常处理原理

SpringBoot中有一个@ControllerAdvice的注解,使用该注解表示开启了全局异常的捕获,只需在自定义一个方法使用ExceptionHandler注解,然后定义捕获异常的类型即可对这些捕获的异常进行统一的处理。

这一部分可以做成一个公共组件,其他项目引入即可,代码这样看上去,更舒服。

1.定义若干通用异常

异常的父类:BaseException,其他异常都集成这个父类

@Data
public abstract class BaseException extends RuntimeException {
    private Integer code;
    private String message;

    public BaseException(Integer code, String message) {
        super(message);
        this.code = code;
        this.message = message;
    }
}

其他:
– InvalidParameterException
– BizException
– ServiceException
– ResourceNotFoundException
– APIException

2.异常处理切面

GlobalExceptionHandlingAdvice 注解

@ControllerAdvice
public class GlobalExceptionHandlingAdvice {

    @ExceptionHandler(NoHandlerFoundException.class)
    public ResponseEntity<ErrorResult> noHandlerFoundException(NoHandlerFoundException ex, HttpServletRequest request) {
        ErrorResult errorResult = new ErrorResult(ResultCode.RESOURCE_NOT_FOUND.getCode());
        errorResult.setMessage(ResultCode.RESOURCE_NOT_FOUND.getMessage());
        ResponseEntity<ErrorResult> entity = new ResponseEntity<>(errorResult, HttpStatus.NOT_FOUND);
        return entity;
    }

    @ExceptionHandler({RuntimeException.class, Exception.class})
    public ResponseEntity<ErrorResult> handleException(RuntimeException ex, HttpServletRequest request) {
        ErrorResult errorResult = new ErrorResult(ResultCode.SERVER_ERROR.getCode());
        errorResult.setMessage(ex.getMessage());
        ResponseEntity<ErrorResult> entity = new ResponseEntity<>(errorResult, HttpStatus.INTERNAL_SERVER_ERROR);
        return entity;
    }

    @ExceptionHandler(InvalidParameterException.class)
    public ResponseEntity<ErrorResult> handleInvalidParameterException(RuntimeException ex, HttpServletRequest request) {
        ErrorResult errorResult = new ErrorResult(ResultCode.PARAMETER_IS_INVALID.getCode());
        errorResult.setMessage(ex.getMessage());
        ResponseEntity<ErrorResult> entity = new ResponseEntity<>(errorResult, HttpStatus.BAD_REQUEST);
        return entity;
    }

    @ExceptionHandler(ResourceNotFoundException.class)
    public ResponseEntity<ErrorResult> handleResourceNotFoundException(RuntimeException ex, HttpServletRequest request) {
        ErrorResult errorResult = new ErrorResult(ResultCode.RESOURCE_NOT_FOUND.getCode());
        errorResult.setMessage(ex.getMessage());
        ResponseEntity<ErrorResult> entity = new ResponseEntity<>(errorResult, HttpStatus.NOT_FOUND);
        return entity;
    }

    @ExceptionHandler(BizException.class)
    public ResponseEntity<ErrorResult> handleInternalServerException(BizException ex, HttpServletRequest request) {
        ErrorResult errorResult = new ErrorResult(ex.getCode());
        errorResult.setMessage(ex.getMessage());
        ResponseEntity<ErrorResult> entity = new ResponseEntity<>(errorResult, HttpStatus.INTERNAL_SERVER_ERROR);
        return entity;
    }

}

3.异常信息的数据格式

定义一个ErrorResult,倘若异常出现,那么GlobalExceptionHandlingAdvice 切面负责捕获,并重写返回结果。

@Data
public class ErrorResult {
    private Integer code;
    private String message;

    public ErrorResult(Integer code) {
        this.code = code;
    }

    public ErrorResult(Integer code, String message) {
        this.code = code;
        this.message = message;
    }
}

(完)

发表评论

邮箱地址不会被公开。 必填项已用*标注