兜兜零元 发表于 2023-10-2 06:55:25

封装全局异常处理

目录

[*]1 定义错误码类
[*]2 定义业务异常类
[*]3 全局异常处理器
[*]4 使用
[*]5 前端请求效果
[*]总结

1 定义错误码类

​        可以定义各种错误码枚举,比如业务,系统相关的报错信息
/**
* 错误代码
* 错误码
*
* @author leovany
* @date 2023/09/23
*/
public enum ErrorCode {
    SUCCESS(0, "success", ""),
    ERROR_PARAMS(40000, "请求参数错误", ""),
    ERROR_NULL(40001, "请求数据为空", ""),
    ERROR_LOGIN(40100, "未登录", ""),
    ERROR_NO_AUTH(41001, "无权限", ""),
    ERROR_SYSTEM(50000, "系统内部异常", "")
    ;


    /**
   * 错误码ID
   */
    private final int code;

    /**
   * 错误码信息
   */
    private final String message;

    /**
   * 错误码描述(详情)
   */
    private final String description;

    ErrorCode(int code, String message, String description) {
      this.code = code;
      this.message = message;
      this.description = description;
    }

    public int getCode() {
      return code;
    }

    public String getMessage() {
      return message;
    }

    public String getDescription() {
      return description;
    }
}2 定义业务异常类


[*]相对于 java 的异常类,支持更多字段
扩展了 code和description两个字段
[*]自定义构造函数,更灵活 / 快捷的设置字段
import com.leovany.usercenter.common.ErrorCode;

/**
* 业务异常
* 自定义业务异常类
*
* @author leovany
* @date 2023/09/23
*/
public class BusinessException extends RuntimeException {

    /**
   * 错误码
   */
    private final int code;

    /**
   * 描述
   */
    private final String description;

    /**
   * 业务异常
   *
   * @param message   信息
   * @param code      错误码
   * @param description 描述
   */
    public BusinessException(String message, int code, String description) {
      super(message);
      this.code = code;
      this.description = description;
    }

    /**
   * 业务异常
   *
   * @param errorCode 错误代码
   */
    public BusinessException(ErrorCode errorCode) {
      super(errorCode.getMessage());
      this.code = errorCode.getCode();
      this.description = errorCode.getDescription();
    }

    /**
   * 业务异常
   *
   * @param errorCode   错误代码
   * @param description 描述
   */
    public BusinessException(ErrorCode errorCode, String description) {
      super(errorCode.getMessage());
      this.code = errorCode.getCode();
      this.description = description;
    }

    public int getCode() {
      return code;
    }

    public String getDescription() {
      return description;
    }
}3 全局异常处理器


[*]通过Spring AOP实现,在调用方法前后进行额外的处理
[*]作用

[*]捕获代码中所有的异常,让前端得到更详细的业务报错信息
[*]屏蔽掉项目框架本身的异常,不暴露服务器的内部状态
[*]集中处理,比如还可以做记录日志

import com.leovany.usercenter.common.ResultVO;
import com.leovany.usercenter.common.ErrorCode;
import com.leovany.usercenter.common.ResultUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
* 全局异常处理类
*/
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    /**
   * 处理异常-BusinessException
   * @param e
   * @return
   */
    @ExceptionHandler(BusinessException.class)
    public ResultVO<?> businessExceptionHandler(BusinessException e){
      log.error("businessException:" + e.getMessage(),e);
      return ResultUtils.error(e.getCode(),e.getMessage(),e.getDescription());
    }

    /**
   * 处理异常-RuntimeException
   * @param e
   * @return
   */
    @ExceptionHandler(RuntimeException.class)
    public ResultVO<?> runtimeExceptionHandler(RuntimeException e){
      log.error("runtimeException:" + e);
      return ResultUtils.error(ErrorCode.ERROR_SYSTEM,e.getMessage());
    }
}4 使用

​        throw new BusinessException可以在方法中,任意地方抛出,很方便

[*]示例代码
@PostMapping("/login")
public ResultVO<User> userLogin(@RequestBody UserLoginRequest userLoginRequest, HttpServletRequest request) {

    String userAccount = userLoginRequest.getUserAccount();
    String userPassword = userLoginRequest.getUserPassword();

    if (StringUtils.isAnyBlank(userAccount, userPassword)) {
      throw new BusinessException(ErrorCode.ERROR_PARAMS);
    }
    User user = userService.doLogin(userAccount, userPassword, request);
    return ResultUtils.success(user);
}

[*]代码对比
https://img2023.cnblogs.com/other/3272173/202309/3272173-20230924111434754-1878576779.png
5 前端请求效果

https://img2023.cnblogs.com/other/3272173/202309/3272173-20230924111435134-1656258708.png
总结

​        通过封装全局异常处理,对异常信息做了统一处理,让前端得到更详细的业务信息,同时保证系统的安全性(不会暴露系统内部信息),在代码上对参数校验等方面提供更加方便的形式。
本文由博客一文多发平台 OpenWrite 发布!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: 封装全局异常处理