天天看点

微服务项目错误码规范和多语言的错误消息

作者:简简单单程序员

在微服务项目中出现错误后最快定位错误的办法就是有一个明确的错误码提示,而微服务项目中往往由不同的人开发不同的模块,这是如果没有统一的错误码规范会导致多个模块出现一个错误码而含义不同导致问题排查的困难。所以我们需要对错误码格式做定义。统一的错误码有以下几个优点。

  1. 一致性和可维护性:微服务架构通常由多个服务组成,这些服务之间可能存在着复杂的调用关系。错误码规范可以确保各个服务在处理错误时保持一致性,统一使用相同的错误码表示特定的错误类型。这样可以提高项目的可维护性,降低代码的复杂性,并使团队成员更容易理解和处理错误。
  2. 故障排查和定位:在微服务架构中,由于服务之间的相互调用,错误可能会在多个服务之间传播。如果每个服务都使用不同的错误码表示相同的错误类型,将会给故障排查和定位带来困难。错误码规范可以提供一套统一的错误码体系,使得定位故障点和排查问题更加高效。
  3. 可读性和可理解性:错误码规范可以提供有意义且易于理解的错误码,使得开发人员、测试人员和运维人员能够快速理解错误的原因和类型。这有助于团队成员之间的沟通和协作,并降低解释错误原因的时间和成本。
  4. 错误处理和容错能力:通过错误码规范,可以定义不同错误类型的处理策略和行为,例如重试、回滚、降级等。这有助于实现系统的容错能力,提高系统的稳定性和可靠性。
  5. 用户体验和错误反馈:通过错误码规范,可以提供统一的错误提示信息,向用户提供更友好和一致的错误反馈。用户可以根据错误码快速了解错误的原因,并采取相应的操作或寻求帮助。

代码实现

类名:MessageCode

路径:

platform-module/platform-module-starter/platform-module-starter-message/src/main/java/com/tinem/platform/module/starter/sdk/MessageCode.java           
package com.tinem.platform.module.starter.sdk;

import cn.hutool.core.util.StrUtil;
import lombok.Getter;

import java.util.*;

/**
 * @author fzh
 * @version v1
 * @program: platform
 * @className MessageCode
 * @description code 枚举分段
 *                   下划线【_】  为分段标志
 *                   中划先【-】  为单词标志
 *                   第一段【SUCCESS,ERROR】
 *                      SUCCESS 代表成功
 *                      ERROR 代表失败
 *                   第二段【模块名称】
 *                      例如: PLATFORM-CLOUD-SERVICE-LINK
 *                   第三段【业务】
 *                   第四段【错误原因】
 * @site
 * @company
 * @create 2021-06-26 12:24
 */
@Getter
public class MessageCode {
    public final static List<MessageCode> MESSAGE_CODE_LIST = new ArrayList<>();

    /** 成功 */
    public final static MessageCode SUCCESS = new MessageCode("SUCCESS",new HashMap<Locale,String>(){{
        put(Locale.US,"success");
        put(Locale.SIMPLIFIED_CHINESE,"成功");
    }});

    /** 未知错误 */
    public final static MessageCode ERROR_COMMONS_UNKNOWN = new MessageCode("ERROR_COMMONS_UNKNOWN",new HashMap<Locale,String>(){{
        put(Locale.US,"system error:{0}");
        put(Locale.SIMPLIFIED_CHINESE,"系统错误:{0}");
    }});
    public final static MessageCode ERROR_COMMONS_404 = new MessageCode("ERROR_COMMONS_404",new HashMap<Locale,String>(){{
        put(Locale.US,"Service:{0}; Method:{1} is 404");
        put(Locale.SIMPLIFIED_CHINESE,"Service:{0}; Method:{1} is 404");
    }});
    public final static MessageCode ERROR_COMMONS_CLIENT_TIME = new MessageCode("ERROR_COMMONS_CLIENT_TIME",new HashMap<Locale,String>(){{
        put(Locale.US,"Client time error: {0}; Server time: {1}");
        put(Locale.SIMPLIFIED_CHINESE,"客户端时间错误:{0}; 服务器时间:{1}");
    }});
    /** 参数验证失败 */
    public final static MessageCode ERROR_COMMONS_REQUEST_REPEAT = new MessageCode("ERROR_COMMONS_REQUEST_REPEAT",new HashMap<Locale,String>(){{
        put(Locale.US,"Duplicate request:{0}");
        put(Locale.SIMPLIFIED_CHINESE,"请求重复:{0}");
    }});
    /** 参数验证失败 */
    public final static MessageCode ERROR_COMMONS_PARAMS = new MessageCode("ERROR_COMMONS_PARAMS",new HashMap<Locale,String>(){{
        put(Locale.US,"parameter validation failed:[{0}]");
        put(Locale.SIMPLIFIED_CHINESE,"参数验证失败:[{0}]");
    }});
    /** 参数验证失败 */
    public final static MessageCode ERROR_COMMONS_PARAMS_FIELD = new MessageCode("ERROR_COMMONS_PARAMS_FIELD",new HashMap<Locale,String>(){{
        put(Locale.US,"{0}");
        put(Locale.SIMPLIFIED_CHINESE,"{0}");
    }});
    /** 参数验证失败 */
    public final static MessageCode ERROR_COMMONS_SERVER = new MessageCode("ERROR_COMMONS_SERVER",new HashMap<Locale,String>(){{
        put(Locale.US,"server error:[{0}]");
        put(Locale.SIMPLIFIED_CHINESE,"服务异常:[{0}]");
    }});
    public final static MessageCode ERROR_COMMONS_ENCRYPTION_TYPE = new MessageCode("ERROR_COMMONS_ENCRYPTION_TYPE",new HashMap<Locale,String>(){{
        put(Locale.US,"Encryption type error, unrecognized encryption type");
        put(Locale.SIMPLIFIED_CHINESE,"加密类型错误,不识别的加密类型:{0}");
    }});
    public final static MessageCode ERROR_COMMONS_LIMIT_SENTINEL = new MessageCode("ERROR_COMMONS_LIMIT_SENTINEL",new HashMap<Locale,String>(){{
        put(Locale.US,"Request is restricted");
        put(Locale.SIMPLIFIED_CHINESE,"请求被限流");
    }});
    // -------------------------------------------------platform-cloud-service-user-------------------------------------
    public final static MessageCode ERROR_PLATFORM_CLOUD_SERVICE_USER_MOBILE = new MessageCode("ERROR_PLATFORM_CLOUD_SERVICE_USER_MOBILE",new HashMap<Locale,String>(){{
        put(Locale.US,"The mobile phone has been bound to other accounts");
        put(Locale.SIMPLIFIED_CHINESE,"手机已绑定其他账号");
    }});
    public final static MessageCode ERROR_PLATFORM_CLOUD_SERVICE_USER_EMAIL = new MessageCode("ERROR_PLATFORM_CLOUD_SERVICE_USER_EMAIL",new HashMap<Locale,String>(){{
        put(Locale.US,"Email has been bound to other accounts");
        put(Locale.SIMPLIFIED_CHINESE,"邮箱已绑定其他账号");
    }});
    public final static MessageCode ERROR_PLATFORM_CLOUD_SERVICE_USER_PASSWORD = new MessageCode("ERROR_PLATFORM_CLOUD_SERVICE_USER_PASSWORD",new HashMap<Locale,String>(){{
        put(Locale.US,"Password incorrect");
        put(Locale.SIMPLIFIED_CHINESE,"密码错误");
    }});
    /** 未知错误 */
    public final static MessageCode ERROR_SESSION_NOT_FIND = new MessageCode("ERROR_SESSION_NOT_FIND",new HashMap<Locale,String>(){{
        put(Locale.US,"session not find");
        put(Locale.SIMPLIFIED_CHINESE,"会话不存在,请确认请求参数!");
    }});
    public final static MessageCode ERROR_SESSION_NOT_AUTHORIZE = new MessageCode("ERROR_SESSION_NOT_AUTHORIZE",new HashMap<Locale,String>(){{
        put(Locale.US,"Access to unauthorized url");
        put(Locale.SIMPLIFIED_CHINESE,"访问未授权url");
    }});
    public final static MessageCode ERROR_COUNTRY_BLACK_LIST = new MessageCode("ERROR_COUNTRY_BLACK_LIST",new HashMap<Locale,String>(){{
        put(Locale.US,"Your country has not opened services yet, please look forward to it!");
        put(Locale.SIMPLIFIED_CHINESE,"您所在的国家暂未开放服务,敬请期待!");
    }});
    // -------------------------------------------------platform-cloud-service-pay-------------------------------------
    public final static MessageCode ERROR_PLATFORM_CLOUD_SERVICE_ORDER_NOT_FIND = new MessageCode("ERROR_PLATFORM_CLOUD_SERVICE_ORDER_NOT_FIND",new HashMap<Locale,String>(){{
        put(Locale.US,"order id:{0},is not find.");
        put(Locale.SIMPLIFIED_CHINESE,"找到不订单id:{0}.");
    }});
    public final static MessageCode ERROR_PLATFORM_CLOUD_SERVICE_ORDER_STATUS = new MessageCode("ERROR_PLATFORM_CLOUD_SERVICE_ORDER_STATUS",new HashMap<Locale,String>(){{
        put(Locale.US,"order id:{0},status:{1} is error.");
        put(Locale.SIMPLIFIED_CHINESE,"订单{}状态{}错误.");
    }});
    public final static MessageCode ERROR_PLATFORM_CLOUD_SERVICE_ORDER_EXPIRE = new MessageCode("ERROR_PLATFORM_CLOUD_SERVICE_ORDER_EXPIRE",new HashMap<Locale,String>(){{
        put(Locale.US,"order id:{0},status:{1} is expire.");
        put(Locale.SIMPLIFIED_CHINESE,"订单{}状态{}过期.");
    }});
    public final static MessageCode ERROR_PLATFORM_CLOUD_SERVICE_ORDER_PAY_ERROR = new MessageCode("ERROR_PLATFORM_CLOUD_SERVICE_ORDER_PAY_ERROR",new HashMap<Locale,String>(){{
        put(Locale.US,"order id:{0},pay:{1} is error.");
        put(Locale.SIMPLIFIED_CHINESE,"订单{}支付失败,原因:{1}.");
    }});
    public final static MessageCode ERROR_PLATFORM_CLOUD_SERVICE_ORDER_PAY_CHANNEL_NOT_FIND = new MessageCode("ERROR_PLATFORM_CLOUD_SERVICE_ORDER_PAY_CHANNEL_NOT_FIND",new HashMap<Locale,String>(){{
        put(Locale.US,"order pay channel:{0},is not find.");
        put(Locale.SIMPLIFIED_CHINESE,"找不到订单支付渠道:{0}.");
    }});
    // -------------------------------------------------platform-cloud-web-gateway--------------------------------------
    public final static MessageCode ERROR_PLATFORM_CLOUD_WEB_GATEWAY_CLIENT_NOT_FIND = new MessageCode("ERROR_PLATFORM_CLOUD_WEB_GATEWAY_CLIENT_NOT_FIND",new HashMap<Locale,String>(){{
        put(Locale.US,"403 forbidden client:[{0}]");
        put(Locale.SIMPLIFIED_CHINESE,"客户端id错误:{0}");
    }});
    public final static MessageCode ERROR_PLATFORM_CLOUD_WEB_GATEWAY_SCOPE_NOT_FIND = new MessageCode("ERROR_PLATFORM_CLOUD_WEB_GATEWAY_SCOPE_NOT_FIND",new HashMap<Locale,String>(){{
        put(Locale.US,"403 forbidden scope:[{0}]");
        put(Locale.SIMPLIFIED_CHINESE,"客户端权限不足,无法访问:[{0}]");
    }});
    public final static MessageCode ERROR_PLATFORM_CLOUD_WEB_GATEWAY_SIGN_TYPE = new MessageCode("ERROR_PLATFORM_CLOUD_WEB_GATEWAY_SIGN_TYPE",new HashMap<Locale,String>(){{
        put(Locale.US,"Request signature type mismatch");
        put(Locale.SIMPLIFIED_CHINESE,"请求签名类型不匹配.客户端需要签名类型:{0}; 上传签名类型: {1}");
    }});
    public final static MessageCode ERROR_PLATFORM_CLOUD_WEB_GATEWAY_SIGN = new MessageCode("ERROR_PLATFORM_CLOUD_WEB_GATEWAY_SIGN",new HashMap<Locale,String>(){{
        put(Locale.US,"Request signature mismatch");
        put(Locale.SIMPLIFIED_CHINESE,"请求签名不匹配.");
    }});
    public final static MessageCode ERROR_PLATFORM_CLOUD_WEB_GATEWAY_CRYPTO_TYPE = new MessageCode("ERROR_PLATFORM_CLOUD_WEB_GATEWAY_CRYPTO_TYPE",new HashMap<Locale,String>(){{
        put(Locale.US,"The requested encryption type does not match,{},{}");
        put(Locale.SIMPLIFIED_CHINESE,"请求加密类型不匹配.客户端需要加密类型:{0}; 上传加密类型: {1}");
    }});

    // -------------------------------------------------platform-cloud-web-auth-----------------------------------------

    public final static MessageCode VERIFICATION_CODE_VALID_FOR_FIVE_MINUTES = new MessageCode("VERIFICATION_CODE_VALID_FOR_FIVE_MINUTES",new HashMap<Locale,String>(){{
        put(Locale.US,"The email verification code is valid for {0} minutes. Do not apply for multiple verification codes");
        put(Locale.SIMPLIFIED_CHINESE,"邮箱验证码{0}分钟有效,请勿多次发送");
    }});

    public final static MessageCode ERROR_PLATFORM_CLOUD_WEB_AUTH_CODE = new MessageCode("ERROR_PLATFORM_CLOUD_WEB_AUTH_CODE",new HashMap<Locale,String>(){{
        put(Locale.US,"Mailbox verification code error");
        put(Locale.SIMPLIFIED_CHINESE,"邮箱验证码错误");
    }});
    public final static MessageCode THE_GRAPHIC_VERIFICATION_CODE_IS_INCORRECT = new MessageCode("THE_GRAPHIC_VERIFICATION_CODE_IS_INCORRECT",new HashMap<Locale,String>(){{
        put(Locale.US,"Graphic verification code error");
        put(Locale.SIMPLIFIED_CHINESE,"图形验证码错误");
    }});
    public final static MessageCode ERROR_PLATFORM_CLOUD_WEB_AUTH_CODE_IMAGE = new MessageCode("ERROR_PLATFORM_CLOUD_WEB_AUTH_CODE_IMAGE",new HashMap<Locale,String>(){{
        put(Locale.US,"Please fill in the picture verification code");
        put(Locale.SIMPLIFIED_CHINESE,"请填写图片验证码");
    }});
    public final static MessageCode ERROR_PLATFORM_CLOUD_WEB_AUTH_CODE_TO = new MessageCode("ERROR_PLATFORM_CLOUD_WEB_AUTH_CODE_TO",new HashMap<Locale,String>(){{
        put(Locale.US,"Unrecognized receiver, please enter email or mobile phone number");
        put(Locale.SIMPLIFIED_CHINESE,"不能识别的接收方,请输入邮箱或者手机号");
    }});
    public final static MessageCode ERROR_PLATFORM_CLOUD_WEB_AUTH_CLIENT_IP = new MessageCode("ERROR_PLATFORM_CLOUD_WEB_AUTH_CODE_TO",new HashMap<Locale,String>(){{
        put(Locale.US,"Client IP is not in the whitelist");
        put(Locale.SIMPLIFIED_CHINESE,"客户端IP不在白名单");
    }});

    // -------------------------------------------------platform-cloud-web-websocket------------------------------------
    public final static MessageCode ERROR_PLATFORM_CLOUD_WEB_WEBSOCKET_SESSION_NOT_FIND = new MessageCode("ERROR_PLATFORM_CLOUD_WEB_WEBSOCKET_SESSION_NOT_FIND",new HashMap<Locale,String>(){{
        put(Locale.US,"success");
        put(Locale.SIMPLIFIED_CHINESE,"未找到session:{0}");
    }});
    public final static MessageCode ERROR_PLATFORM_CLOUD_WEB_WEBSOCKET_CONNECTION_STATUS_IS_NOT_CONNECTION = new MessageCode("ERROR_PLATFORM_CLOUD_WEB_WEBSOCKET_CONNECTION_STATUS_IS_NOT_CONNECTION",new HashMap<Locale,String>(){{
        put(Locale.US,"success");
        put(Locale.SIMPLIFIED_CHINESE,"链接未初始化");
    }});

    // -------------------------------------------------platform-cloud-web-file------------------------------------

    public final static MessageCode ERROR_PLATFORM_CLOUD_WEB_FILE_GENERATION_FAILED = new MessageCode("ERROR_PLATFORM_CLOUD_WEB_FILE_GENERATION_FAILED",new HashMap<Locale,String>(){{
        put(Locale.US,"File generation failed");
        put(Locale.SIMPLIFIED_CHINESE,"文件生成失败");
    }});
    public final static MessageCode ERROR_PLATFORM_CLOUD_WEB_FILE_SIZE_LIMIT = new MessageCode("ERROR_PLATFORM_CLOUD_WEB_FILE_SIZE_LIMIT",new HashMap<Locale,String>(){{
        put(Locale.US,"File generation failed");
        put(Locale.SIMPLIFIED_CHINESE,"当前文件大小超过限制");
    }});
    public final static MessageCode ERROR_PLATFORM_CLOUD_WEB_STORAGE_SIZE_LIMIT = new MessageCode("ERROR_PLATFORM_CLOUD_WEB_STORAGE_SIZE_LIMIT",new HashMap<Locale,String>(){{
        put(Locale.US,"File generation failed");
        put(Locale.SIMPLIFIED_CHINESE,"渠道存储空间不足");
    }});

    String name;
    Map<Locale,String> localMessage;

    public MessageCode(String name,Map<Locale,String> localMessage){
        this.name = name;
        this.localMessage = localMessage;
        MESSAGE_CODE_LIST.add(this);
    }

    public static List<MessageCode> values(){
        return MESSAGE_CODE_LIST;
    }
    public static MessageCode valueOf(String name){
        Optional<MessageCode> messageCode = MESSAGE_CODE_LIST.stream().filter(mc -> mc.name().equalsIgnoreCase(name)).findFirst();
        if(messageCode.isPresent()){
            return messageCode.get();
        }
        throw new IllegalArgumentException("No enum "+name);
    }

    public String name(){return name;};


    public String getMessage(Locale locale,Object... params){
        if(locale == null){
            locale = Locale.US;
        }
        return StrUtil.indexedFormat(localMessage.containsKey(locale) ? localMessage.get(locale) : localMessage.get(Locale.US),params);
    }
    public String getMessage(Object... params){
        return getMessage(Locale.US,params);
    }

}           

在我们定义好错误码后再代码中使用

UserException代表由用户引起的异常,例如参数错误,访问一个不存在的资源等。

SystemException代表系统错误,例如数据库链接失败,网络错误,内存溢出等。

微服务项目错误码规范和多语言的错误消息

这两个异常都有一个构造函数,第一个参数是错误码,第二个参数是错误消息中的参数。

微服务项目错误码规范和多语言的错误消息
微服务项目错误码规范和多语言的错误消息
微服务项目错误码规范和多语言的错误消息

Postman测试

这里我们用一个错误的客户端时间发送请求,然后分别切换语言为中文和英文,查看网关返回的错误消息。

  1. 英文
微服务项目错误码规范和多语言的错误消息
微服务项目错误码规范和多语言的错误消息
  1. 中文
微服务项目错误码规范和多语言的错误消息
微服务项目错误码规范和多语言的错误消息

继续阅读