Spring Boot自定义异常并返回

53 阅读2分钟

异常抛出和返回

1、创建一个异常继承RuntimeException

/**
 * @author ly
 * @date 2022年11月9日17:34:01
 */
    public class CustomException extends RuntimeException {
    private static final long serialVersionUID = 1L;

    private String msg;
    private int code = 500;

    public CustomException(String msg) {
        super(msg);
        this.msg = msg;
    }

    public CustomException(String msg, Throwable e) {
        super(msg, e);
        this.msg = msg;
    }

    public CustomException(String msg, int code) {
        super(msg);
        this.msg = msg;
        this.code = code;
    }

    public CustomException(String msg, int code, Throwable e) {
        super(msg, e);
        this.msg = msg;
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

}

2、代码中如果需要异常直接抛出,如下:

    @GetMapping("/{id}")
    public R<Book> getById(@PathVariable("id") Integer id)  {
        if (true) {
            //使用throw手动抛出异常
            throw new CustomException("手动抛出异常");
        }
        return R.ok(bookService.getById(id));
    }

此时代码走到此处如果有问题就可以把一场抛出,在控制台/日志中打印出来。

image-20221109212356688.png

3、把报错数据捕获后返回

此时可以手动捕获到报错了,但是还需要告诉前端因为什么原因报错,前端可以把报错展示给用户看,以用来调整自己的数。

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    @Resource
    private MessageSource messageSource;

    /**
     * 处理自定义异常
     */
    //捕获异常的名字,自己创建的异常名字什么,这里写什么,这样就可以在自己手动抛出异常时此处就可以捕获到异常
    @ExceptionHandler(CustomException.class)
    //http默认状态码 HttpStatus Http状态码枚举 INTERNAL_SERVER_ERROR为500
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public R<String> handleCustomException(CustomException e) {
        //打印message中的内容
        log.error("CustomException ex={}", e.getMessage(), e);
        //获取抛出异常的code 默认为500
        int code = e.getCode();
        try {
            //获取自己写的异常原因
            String msg = e.getMsg();
            if (msg != null) {
                //不为空,进入,创建返回的参数类
                R<String> r = new R<>();
                //添加code
                r.setCode(code);
                //添加msg
                r.setMsg(msg);
                return r;
            }
        } catch (NoSuchMessageException ex) {
            log.warn("CustomException no message defined", ex);
        }
        return  R.error();
    }



    /**
     * 全局异常.
     *
     * @param e the e
     * @return R
     */
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public R<String> exception(Exception e) {
        log.error("全局异常信息 ex={}", e.getMessage(), e);
        return R.error();
    }

    /**
     * validation Exception
     * 
     * @param exception 报错原因
     * @return R
     */
    @ExceptionHandler({MethodArgumentNotValidException.class, BindException.class})
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public R<String> bodyValidExceptionHandler(MethodArgumentNotValidException exception) {
        List<FieldError> fieldErrors = exception.getBindingResult().getFieldErrors();
        R<String> result = new R<>();
        String msg = null;
        try {
            String messageKey = fieldErrors.get(0).getDefaultMessage();
            if (messageKey != null && messageKey.startsWith("{")) {
                messageKey = messageKey.replace("{", "");
                messageKey = messageKey.replace("}", "");
                msg = messageSource.getMessage(messageKey, null, LocaleContextHolder.getLocale());
            }
        } catch (NoSuchMessageException ex) {
            log.warn("validation exception no message defined", ex);
        }
        if (msg == null) {
            msg = fieldErrors.get(0).getDefaultMessage();
        }
        result.setMsg(msg);
        log.warn(fieldErrors.get(0).getDefaultMessage());
        return result;
    }
}