- 为什么要统一错误码和全局异常处理(好处)?
对于后端开发,当引入非法请求导致程序抛出异常时,如NPE,我们可以查看日志快速定位程序错误点进行修改。但是对于前端人员来说,有时候很难理解查看日志。因此,我们应该统一管理一些可能抛出异常的地方,抛出一些对前端或用户友好的信息(如果密码错误,让用户知道密码错误)。在这个过程中,我们可以通过定制错误代码来区分不同信息的安全性或严重性,或者让其他人知道它是成功的还是自己的操作问题,或者服务器问题。
- 怎么定义
HTTP响应码可以模仿定义。
例如,200是成功的请求,4xx是客户端问题,5xx是服务器问题,然后详细说明具体的响应代码和响应信息。确保响应代码和响应信息没有歧义,最好是一针见血。
- 怎么实现
统一java中的错误码,我们可以考虑枚举类型,列出我们所需要的所有错误码,字段定义是知名的。
package com.xc.project.common;/** * 定制错误代码 * @author xc */public enum ErrorCode { SUCCESS(0, "ok"), PARAMS_ERROR(40000, “请求参数错误”), NOT_LOGIN_ERROR(40100, “未登录”), NO_AUTH_ERROR(40101, “无权”), NOT_FOUND_ERROR(40400, “不存在请求数据”, FORBIDDEN_ERROR(40300, "禁止访问"), SYSTEM_ERROR(50000, "系统内部异常"), OPERATION_ERROR(50001, “操作失败”); /** * 状态码 */ private final int code; /** * 信息 */ private final String message; ErrorCode(int code, String message) { this.code = code; this.message = message; } public int getCode() { return code; } public String getMessage() { return message; }}
统一异常处理,首先定义自己的异常类继承RuntimeException
package com.xc.project.exception;import com.xc.project.common.ErrorCode;/** * 自定义异常类 * @author xc */public class BusinessException extends RuntimeException { /** * 错误码 */ private final int code; // 可以通过自定义code和信息创建 public BusinessException(int code, String message) { super(message); this.code = code; } // 可以通过我们的统一错误码创建 public BusinessException(ErrorCode errorCode) { super(errorCode.getMessage()); this.code = errorCode.getCode(); } // 可以通过现有的code和我们不合理操作的理由来创建 public BusinessException(ErrorCode errorCode, String message) { super(message); this.code = errorCode.getCode(); } public int getCode() { return code; }}
定义全局异常处理类
package com.xc.project.exception;import com.xc.project.common.BaseResponse;import com.xc.project.common.ErrorCode;import com.xc.project.common.ResultUtils;import lombok.extern.slf4j.Slf4j;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.bind.annotation.RestControllerAdvice;/** * 全局异常处理器 * @author xc */@RestControllerAdvice@Slf4jpublic class GlobalExceptionHandler {// 拦截自己的异常类别,然后统一格式返回到前端 @ExceptionHandler(BusinessException.class) public BaseResponse<?> businessExceptionHandler(BusinessException e) { log.error("BusinessException", e); return ResultUtils.error(e.getCode(), e.getMessage()); } @ExceptionHandler(RuntimeException.class) public BaseResponse<?> runtimeExceptionHandler(RuntimeException e) { log.error("RuntimeException", e); return ResultUtils.error(ErrorCode.SYSTEM_ERROR, “系统错误”); }}
规范异常返回,避免冗余错误报告