范文健康探索娱乐情感热点
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

后端开发如何优雅地进行错误码管理

  0. 前言
  在一个项目乃乃至整个团队在所有项目的开发过程中,统一设计和规范使用错误码,是必须要落实的一个点。
  错误码的设计,直接关系到后端接口的条理性和优雅性;错误码的使用,直接关系到开发人员的开发规范和开发效率。
  所以,对错误码进行优雅的管理,是非常有必要的,是一个团队的基石之一。
  下面,我会从如何设计,管理和多语言错误码的具体实现等三个方面一一阐述。1. 设计
  首先,需要对错误码大致分为两类:通用错误码特殊含义错误码
  其次,错误码需要包含的要素:错误码中文错误信息英文错误信息1.1 通用错误码
  主要包含:成功和失败(未知错误)SUCCESS("10000", "成功", "ok"),UNKNOWN_ERROR("-1", "未知错误", "unknown error")1.2 特殊含义错误码和用户相关的错误,如:
  A_PARAM_VALIDATION_ERROR("A0100", "参数校验失败", "parameter validation error")和第三方依赖相关的错误,如:
  B_STORAGE_ERROR("B0100", "持久化存储错误", "storage error")和当前业务系统相关的错误,如:
  C_RESOURCE_OUT_ERROR("C0100", "系统资源异常", "system resource error")2.管理
  由于目前没有人力投入到错误码管理平台的开发,市面上也没有比较合适的开源项目可以使用,因此,暂时使用飞书文档做错误码管理。详情见开放平台错误码管理3.具体实现
  代码侧,首先要有一个枚举类,用于存放所有错误码。
  错误码枚举类public enum ReturnEnum {      /**      * 成功      */     SUCCESS("10000", "成功", "ok"),     /**      * 未知错误      */     UNKNOWN_ERROR("-1", "未知错误", "unknown error"),      /**      * 一级宏观错误码,和用户相关      */     A_USER_CLIENT_ERROR("A0000", "用户端错误", "user client error"),     /**      * 二级宏观错误码,用户传参相关错误      */     A_PARAM_VALIDATION_ERROR("A0100", "参数校验失败", "parameter validation error"),     A_REQ_PARAM_VALIDATION_ERROR("A0101", "传参校验失败", "request parameter validation error"),     A_MAIL_FORMAT_ERROR("A0102", "邮箱格式错误", "mail format error"),     A_PHONE_FORMAT_ERROR("A0103", "手机号格式错误", "phone format error"),      /**      * 二级宏观错误码,用户注册/登录相关错误      */     A_USER_LOGIN_FAIL("A0200", "用户登录失败", "user login failed"),     A_USER_ACCESS_DENIED_ERROR("A0201", "权限不足", "access denied"),     A_USER_AUTHENTICATE_ERROR("A0202", "用户认证失败", "user authenticate failed"),     A_MAIL_EXIST_ERROR("A0203", "邮箱已注册", "mail address already registered"),     A_CAPTCHA_VALIDATION_ERROR("A0204", "验证码校验失败", "captcha validation error"),     A_MAIL_VALIDATION_ERROR("A0205", "邮箱验证码校验失败", "mail code validation error"),     A_USER_NOT_EXIST_ERROR("A0206", "用户不存在", "user not existed"),     A_USER_PASSWORD_ERROR("A0207", "用户名或密码错误", "user or password error"),     A_USER_CHANGE_CODE_ERROR("A0208", "修改密码凭证错误或者已过期", "change password code error or expired"),     A_USER_REGISTER_ERROR("A0209", "用户注册失败", "register error"),     A_USER_EXISTED_ERROR("A0210", "用户已存在", "username already existed"),     A_USER_TOKEN_EXPIRE_ERROR("A0211", "用户token已过期", "user token expired"),       /**      * 一级宏观错误码,和第三方服务相关:数据库,缓存,第三方接口等      */     B_GENERAL_3RD_ERROR("B0000", "一般三方依赖错误", "general 3rd error"),     /**      * 二级宏观错误码,持久化存储错误,主要和 mysql 相关      */     B_STORAGE_ERROR("B0100", "持久化存储错误", "storage error"),     B_SQL_INTEGRITY_CONSTRAINT_VIOLATION_ERROR("B0101", "违反数据库索引约束错误", "sql integrity constraint violation"),     B_DUPLICATE_KEY_ERROR("B0102", "违反数据库唯一索引约束错误", "duplicated key"),     B_QUERY_NO_RESULT("B0103", "没有查询到数据", "no data queried"),     B_MINIO_UPLOAD_URL_ERROR("B0104", "获取文件上传链接错误", "get upload file url error"),      /**      * 二级宏观错误码,缓存存储错误,主要和 redis 相关      */     B_CACHE_ERROR("B0200", "缓存错误", "cache error"),     B_CACHE_REDIS_SET_ERROR("B0201", "缓存写入异常", "cache set error"),     B_CACHE_REDIS_DEL_ERROR("B0202", "缓存删除异常", "cache del error"),     B_CACHE_REDIS_GET_ERROR("B0203", "缓存获取异常", "cache get error"),     /**      * 二级宏观错误码,和第三方接口有关      */     B_3RD_API_ERROR("B0300", "第三方接口异常", "3rd api error"),     B_GITHUB_OAUTH_ERROR("B0301", "github oauth 接口异常", "github oauth api error"),     B_FEISHU_TENANT_TOKEN_ERROR("B0302", "获取飞书tenant token异常", "get feishu tenant token error"),     B_FEISHU_USER_INFO_RREOR("B0303", "获取飞书用户异常", "get feishu user info error"),     B_FEISHU_SEND_MSG_RREOR("B0304", "发送飞书消息异常", "send feishu msg error"),     B_EMAIL_SEND_RREOR("B0305", "发送邮件异常", "send email error"),      /**      * 一级宏观错误码,和当前系统相关:业务逻辑,程序健壮性等      */     C_GENERAL_BUSINESS_ERROR("B0000", "一般业务错误", "general business error"),     /**      * 二级宏观错误码,系统资源异常      */     C_RESOURCE_OUT_ERROR("C0100", "系统资源异常", "system resource error"),     C_MEMORY_OUT_ERROR("C0101", "系统内存异常", "memory out"),     /**      * 二级宏观错误码,业务逻辑错误      */     C_BUSINESS_LOGIC_ERROR("C0200", "业务逻辑错误", "business logic error"),     C_BUSINESS_USER_NOT_FOUND_ERROR("C0201", "未找到用户", "user not found"),     C_BUSINESS_CHANGE_PASSWORD_ERROR("C0202", "修改密码出错", "change password error"),     /**      * 二级宏观错误码,程序鲁棒性异常      */     C_CODE_ROBUST_ERROR("C0200", "程序鲁棒性缺陷", "code robustness weak"),     ;      String msgCode;     String msgCn;     String msgEn; }
  增加一个拦截器LanguageInterceptorpublic class LanguageInterceptor implements HandlerInterceptor {     @Override     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {         String acceptLanguage = request.getHeader(HttpHeaders.ACCEPT_LANGUAGE);         RequestHolderUtil.addLang(acceptLanguage);         return true;     }      @Override     public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {     }      @Override     public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {         RequestHolderUtil.remove();     } }  public class RequestHolderUtil {     private static final ThreadLocal requestHolder = new ThreadLocal();      public RequestHolderUtil() {     }      public static void addLang(String language) {         requestHolder.set(language);     }      public static String getLang() {         return (String)requestHolder.get();     }      public static void remove() {         requestHolder.remove();     } }
  注册拦截器@Configuration public class WebConfig implements WebMvcConfigurer {     @Override     public void addInterceptors(InterceptorRegistry registry) {         registry.addInterceptor(new LanguageInterceptor()).addPathPatterns("/**");     } }
  返回包装类@Data @AllArgsConstructor @Slf4j public class ReturnBase implements Serializable {     private static final long serialVersionUID = 1L;      /**      * 日志跟踪标识      */     public static final String TRACE_ID = "TRACE_ID";      private String traceId;     private String msgCode;     private String msg;     private Object data;     private Integer total;  ...     public static ReturnBase error(ReturnEnum returnEnum) {         return error(returnEnum, RequestHolderUtil.getLang());     }      public static ReturnBase error(ReturnEnum returnEnum, String language) {         String msg;         if (Objects.isNull(language)) {             return new ReturnBase(MDC.get(TRACE_ID), returnEnum.getMsgCode(), returnEnum.getMsgEn(), null, 0);         }         switch(language){             case CommonConstant.SIMPLE_CHINESE:                 msg = returnEnum.getMsgCn();                 break;             default:                 msg = returnEnum.getMsgEn();                 break;         }         return new ReturnBase(MDC.get(TRACE_ID), returnEnum.getMsgCode(), msg, null, 0);     }   ...      public static String MsgFormat(String code, String msg) {         return String.format("%s (error: %s)", msg, code);     } }
  使用示例
  前端发起请求,在header 里携带HttpHeaders. ACCEPT_LANGUAGE=zh-Hans ;
  后端LanguageInterceptor 拦截器拦截后,将ACCEPT_LANGUAGE  塞入当前请求的Threadlocal 变量里;
  后端返回错误码给前端:ReturnBase.error(ReturnEnum. C_GENERAL_BUSINESS_ERROR );
  在ReturnBase.error() 方法中,会根据之前塞入到Threadlocal 里的ACCEPT_LANGUAGE 变量,自动选择返回中文还是英文的错误文案。

B站越来越像腾讯了B站在成为像腾讯一样的国民软件娱乐王国之前,还有很长的路要走。文丨BT财经庆秋B站超越优酷,日活突破6500万,成为仅次于爱腾的第三大长视频平台。8月11日的这则利好消息,并未止住你们的来电铃声是哪首歌呢?追剧的朋友们相信大家都会感同身受,喜爱一部剧自然而然的爱上了这部剧的主题曲!老夫也是,几月前被一部叫恶魔少爷别吻我的玛丽苏剧给迷上瘾了,每当主题曲暗算都画面感十足啊!也推荐大家去看手机里面有没有珍藏很久的美图?分享一下?手机里珍藏的美图不少,都来源于生活中所拍摄作品,现奉几幅,请君指教!作揖作揖作揖作揖拍的花花草草!很爽!1,倒影。2,中国园林。3,大观园。4,大观园。5,世界公园东门。6,新房客人工智能时代,这几大职业即将被淘汰,如何幸免?理解人工智能的原理,就能预测未来。人工智能的本质上本不是简单的机器人就是人工智能。人工智能时代的到来可谓是喜忧参半,霍金比尔盖茨等名人都警告人工智能危险,但人工智能的大势也不可逆转真会营销!传iPhone13Pro将取消256GB存储,iPhone7时代取消64GB9月1日消息,随着一年一度科技春晚苹果新品发布会的临近,关于新款iPhone的消息曝光越来越多。近日,网传iPhone13Pro系列可能会取消256GB存储规格。对于这一操作,不少新能源车减重铝合金与加工需求看涨作者DIGITIMES廖家宜全球对于减碳要求造就新能源车的快速成长,然而汽车大厂现在不只关注于电力系统的研发,更要从材料端为车体减重,从而达到更持久的续航力,未来在电动车商机带动下iOS15Beta8来了!越来越快了今天凌晨,苹果向开发者推送了iOS15beta8更新,与上次更新仅隔了6天的时间,更新速度越来越快了,说明正式版已经不远了。本次更新的版本号为19A5340a,这次更新,未发现实际热搜腾讯放弃音乐独家版权小米之家被洗劫电子驾照正式上线Windows11正式版公布推送时间微软现宣布Windows11推送时间,将于2021年10月5日开始为符合条件的Windows10个人电脑推出免费升级服务,预装Windows11Win11正式版将于10月5日推出Win10用户可免费升级!(附下载)最近,微软在多个渠道宣布将在10月5日推出全新的Windows11正式版,届时所有所有符合条件的设备将会陆续获得Windows11免费升级,在系统设置的Windows更新中就可以直3种Python恶搞脚本,医院的WiFi实在太快了Python无限恶搞朋友电脑,别提有多爽了,哈哈,打造自己的壁纸修改器,电脑无限锁屏,无线弹窗,都在这里!!!修改电脑桌面壁纸工具使用开发环境python3。7,Windows10三甲中医飞入雅鲁藏布大峡谷互联网中医能改变什么?中医药凝聚着深邃的哲学智慧和中华民族几千年的健康养生理念及实践经验。当古老的中医药遇上新生代的互联网,犹如把准了行业的脉搏,开出了一张灵丹妙方。近年来,国家高度重视中医药事业,把中
曝光2K全面屏华为P60Pro,华为P50加速降价趋势,疯狂抢购了曝光1亿像素主摄2K全面屏的华为P60Pro概念机渲染图显示其在外观方面有着较大的改变。曝光1亿像素主摄2K全面屏的华为P60Pro概念机屏幕分辨率为1080P,曝光1亿像素主摄2华为watch系列新品手表华为watch3系列近日华为开售了一款智能运动手表。它属于华为watch系列家族款,主打轻量型运动款手表。华为watch3系列首先它的外观是一块1。64英寸456280屏幕分辦率AMOLED彩色屏幕,IntelCPU的发展历程(十)2008年11月Intel推出了基于45nm制作工艺的新架构Nehalem,发布了Corei7965E920处理器。从这一代产品开始,英特儿放弃了Core2Duo的命名方式,改为C买联想笔记本还是Thinkpad无论是以前的IBM还是现在的联想,他们都让ThinkPad这一品牌在商务领域保持着较高的地位。小黑之所以被大家推崇,一方面是它经典的外观,棱角分明的沉稳风格非常符合商务人士气质,另天玑8100才叫真香芯片,150W闪充5000万三摄,仅2499元从今年上半年的情况来看,手机市场不建议大家考虑旗舰机,特别是安卓阵营这边,骁龙8Gen1和天玑9000都没有太好的表现,虽然拥有极为强悍的性能参数,但实际体验由于发热问题,其使用起中国广电即将放出新号段,或将改变三大运营商现状?本文原创,请勿抄袭和搬运,违者必究三大运营商一直是用户通信网络服务的主体,不论好坏,也没有别的选择了。以三大运营商一贯的风格,服务质量基本没有太大的差异。而对于这些情况,网上的评价广西汽车集团企业孵化器升格为国家级近日,科技部公布2021年度国家级科技企业孵化器名单,广西3家孵化器上榜,其中广西汽车集团菱动科技企业孵化器成为广西唯一一家专业型汽车领域国家级科技企业孵化器。菱动科技企业孵化器是中国回避了没有人预见到的加密货币灾难1。最近加密货币市场陷入了低迷,爆仓无数,号称稳定币的Luna币归零,沉重打击了市场。2。查理芒格早先评论说,中国规避了加密货币在本国使用,这让我们看起来很愚蠢。随着市场崩溃,越来这一周POS套现量刑修订,敏付传化汇元天喻等发布财报这一周为移动支付网打造的轻阅读栏目,关注移动支付行业一周热点,涵盖各大新技术创新及应用领域等。点击标题可直接阅读原文。最高检公安部发布支付相关新规4月29日,最高人民检察院公安部联40万人爆仓!虚拟货币暴跌,千亿大佬财富蒸发90,特斯拉也入坑在不少玩家眼里,数字货币可以避免进入风险,然而5月初虚拟货币比特币跌破3万美元,与此同时美股大跌,苹果特斯拉等高科技企业市值蒸发上百亿,将近四十万的投资者亏损。面对这样的状况,股市一文讲透信息化与数字化的差异文章来源于公众号洞见学堂作者王勇谢晨颖导读近几年,数字化的概念被炒得火热。从百度搜索指数来看,从2020年开始,数字化的搜索趋势逐渐上涨,并超越了信息化,越来越多的企业都试图向数字