错误码为字符串类型,共5位,分成两个部分:错误产生来源+四位数字编号。

说明:错误产生来源分为A/B/C

  • A表示错误来源于用户,比如参数错误,用户安装版本过低,用户支付超时等问题;
  • B表示错误来源于当前系统,往往是业务逻辑出错,或程序健壮性差等问题;
  • C表示错误来源于第三方服务,比如CDN服务出错,消息投递超时等问题;

四位数字编号从0001到9999,大类之间的步长间距预留100。

编号不与公司业务架构,更不与组织架构挂钩,以先到先得的原则在统一平台上进行,审批生效,编号即被永久固定。

错误码分三级设置::一级宏观错误码、二级宏观错误码、三级详细错误码。

举例:

错误码中文描述说明
A0001用户端错误一级宏观错误码
A0100用户注册错误二级宏观错误码
A0101用户未同意隐私协议三级宏观错误码
A0102注册国家或地区受限
A0110用户名校验失败
A0111用户名已存在
A0112用户名包含敏感词
..................
A0200用户登录异常二级宏观错误码
错误码中文描述说明
B0001系统执行出错一级宏观错误码
B0100系统执行超时二级宏观错误码
错误码中文描述说明
C0001调用第三方服务出错一级宏观错误码
C0100中间件服务出错二级宏观错误码

业务实践

通常,错误码枚举类均实现一接口类,主要是对异常码格式的规范:

public interface IErrorCode {

    /**
     * 错误码
     */
    String code();

    /**
     * 错误信息
     */
    String message();
}

异常码枚举类一般放在基建子模块下的 convention(规约)包下:

为了平台规范性和利于后期拓展,这里将异常码的位数拓展到了 7 位:

public enum BaseErrorCode implements IErrorCode {

    // ========== 一级宏观错误码 客户端错误 ==========
    CLIENT_ERROR("A000001", "用户端错误"),

    // ========== 二级宏观错误码 用户注册错误 ==========
    USER_REGISTER_ERROR("A000100", "用户注册错误"),
    USER_NAME_VERIFY_ERROR("A000110", "用户名校验失败"),
    USER_NAME_EXIST_ERROR("A000111", "用户名已存在"),
    USER_NAME_SENSITIVE_ERROR("A000112", "用户名包含敏感词"),
    USER_NAME_SPECIAL_CHARACTER_ERROR("A000113", "用户名包含特殊字符"),
    PASSWORD_VERIFY_ERROR("A000120", "密码校验失败"),
    PASSWORD_SHORT_ERROR("A000121", "密码长度不够"),
    PHONE_VERIFY_ERROR("A000151", "手机格式校验失败"),

    // ========== 二级宏观错误码 系统请求缺少幂等Token ==========
    IDEMPOTENT_TOKEN_NULL_ERROR("A000200", "幂等Token为空"),
    IDEMPOTENT_TOKEN_DELETE_ERROR("A000201", "幂等Token已被使用或失效"),

    // ========== 一级宏观错误码 系统执行出错 ==========
    SERVICE_ERROR("B000001", "系统执行出错"),
    // ========== 二级宏观错误码 系统执行超时 ==========
    SERVICE_TIMEOUT_ERROR("B000100", "系统执行超时"),

    // ========== 一级宏观错误码 调用第三方服务出错 ==========
    REMOTE_ERROR("C000001", "调用第三方服务出错");

    private final String code;

    private final String message;

    BaseErrorCode(String code, String message) {
        this.code = code;
        this.message = message;
    }

    @Override
    public String code() {
        return code;
    }

    @Override
    public String message() {
        return message;
    }
}

接下来,我们模拟用户恶意请求访问不存在的用户名,即缓存穿透的场景,看一下我们设计的异常码的真实应用。

首先分析,这种情况属于 B 类异常,B 类异常下又属于用户记录信息异常这一二级异常,由于系统在该级别下暂时没有其他的异常,该异常的异常码就可以定义为:B000200:

USER_NULL("B000200", "用户记录不存在")

测试结果:

{
    "code":"B000200”,
    "message'":“用户记录不存在”,
    "data":null,
    "requestId":null,
    "success": false
}

进一步地,还可将与业务有关的异常码单独抽取成业务强关联的异常码枚举类:

此作者没有提供个人介绍
最后更新于 2024-08-25