为什么要使用错误码,直接返回一个错误信息不好么?
下面介绍一下,在程序开发中使用错误码的必要性~
便于排查问题
想象你开了一家奶茶店,顾客下单后可能出现各种问题:
- 没珍珠了(错误码:5001)
- 杯子不够了(错误码:5002)
- 支付失败(错误码:5003)
如果店员直接对顾客喊:“那个…机器坏了(错误码:500)!我也不知道为啥!”,顾客肯定一头雾水。但如果用更加具体的错误码:
- 顾客看到 “错误码 5001”,直接知道 “哦,没珍珠了,换椰果吧”。
- 老板看到 “错误码 5003”,马上检查支付系统。
避免 freestyle、方便统计
对于“用户不存在”这一错误,不同的程序员会有不同的表述,比如:
- 程序员A写:“用户没找到”
- 程序员B写:“用户不存在”
- 程序员C写:“查无此人”
其实都是同一件事,但看起来像三种错误。而用错误码后就可以统一成 “1001”,大家看到这个码,都知道是“用户不存在”。
此外,如果老板需要统计由于“用户不存在”导致的错误数量有多少时,就可以通过 “1001” 去搜。
便于多端协作
比如前端、移动端或第三方服务需要根据错误类型执行不同逻辑(如跳转登录页、展示特定提示)。就可以通过错误码约定行为:
if (errorCode == 401) {
// 跳转登录页
} else if (errorCode == 403) {
// 提示权限不足
}
支持国际化
方法返回错误码,再根据语言环境映射到对应的翻译文本:
// 中文环境
{ "code": 1001, "message": "用户不存在" }
// 英文环境
{ "code": 1001, "message": "User not found" }
最佳实践
1.定义错误码枚举类
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;
}
}
2.方法返回包含错误码信息的通用返回对象
@PostMapping("/add")
public BaseResponse<Long> addChart(@RequestBody ChartAddRequest chartAddRequest, HttpServletRequest request) {
if (chartAddRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
Chart chart = new Chart();
BeanUtils.copyProperties(chartAddRequest, chart);
User loginUser = userService.getLoginUser(request);
chart.setUserId(loginUser.getId());
boolean result = chartService.save(chart);
ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
long newChartId = chart.getId();
return ResultUtils.success(newChartId);
}
3.全局捕获异常
@RestControllerAdvice
@Slf4j
public 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, "系统错误");
}
}