精华内容
下载资源
问答
  • 海康威视sdk开发中返回的错误码

    热门讨论 2015-04-23 21:52:43
    海康威视sdk开发中返回的错误码。有了错误码原因就好找了吗
  • 微信支付退款接口错误码对照表,对照调试中出现的错误代码,查看具体原因
  • 错误码如何设计才合理?

    千次阅读 多人点赞 2020-06-30 14:34:34
    本文分享阿里文娱技术专家长统对于错误码的看法,希望从错误码使用的不同场景讨论得到一个合理的错误码规约,得到一个面向日志错误码标准和一个面向外部传递的错误码标准。一 前言在工作中,接触过不少外部接口,...
    简介:对于错误码的设计,不同的开发团队有不同的风格习惯。本文分享阿里文娱技术专家长统对于错误码的看法,希望从错误码使用的不同场景讨论得到一个合理的错误码规约,得到一个面向日志错误码标准和一个面向外部传递的错误码标准。

    image.png

    一 前言

    在工作中,接触过不少外部接口,其中包括:支付宝,微信支付,微博开发平台,阿里云等等。每家公司错误码风格都不尽相同,有使用纯数字的,有使用纯英文的,也有使用字母和数字组合的。也接触过很多内部系统,错误码设计也不尽相同。

    错误码的输出路径

    面向日志输出

    • 服务内传递,最终是输出到日志。
    • 域内服务间,比如同时大麦电商之间的系统,最终目的是输出到日志。

    面向外部传递

    • 域内向域外
    • 服务端传递到前端
    • OpenAPI 错误码
    • 内部不同域之间

    错误码使用场景

    • 通过错误码配置监控大盘。
    • 通过日志进行问题排查,快速定位问题。
    • 后端服务之间错误码传递。
    • 前端展示的错误提示/OpenAPI。

    本文希望从错误码使用的不同场景讨论得到一个合理的错误码规约,得到一个面向日志错误码标准和一个面向外部传递的错误码标准。

    PS:本文引用全部引自阿里巴巴《Java 开发手册》,下称《手册》。

    二 什么是错误码

    错误码要回答的最根本的问题是,谁的错?错在哪?

    那么一个错误能表示出谁的错和错在哪里就是一个好的错误码吗?答案显然是否定的,这个标准太基础了。

    • 好的错误码必须能够快速知晓错误来源。
    • 好的错误码必须易于记忆和对比。
    • 好的错误码必须能够脱离文档和系统平台达到线下轻量沟通的目的(这个要求比较高)。

    引自《手册》- 异常日志-错误码

    错误码的制定原则:快速溯源、简单易记、沟通标准化。

    说明:错误码想得过于完美和复杂,就像康熙字典中的生僻字一样,用词似乎精准,但是字典不容易随身携带并且简单易懂。
    正例:错误码回答的问题是谁的错?错在哪?
    1)错误码必须能够快速知晓错误来源,可快速判断是谁的问题。
    2)错误码易于记忆和比对(代码中容易 equals)。
    3)错误码能够脱离文档和系统平台达到线下轻量化地自由沟通的目的。

    这个原则写在异常日志-错误码这个章节,我认为同样适用在面向用户的错误码。

    image.png

    三 错误码规范

    错误码定义要有字母也要有数字

    纯数字错误码

    错误码即人性,感性认知+口口相传,使用纯数字来进行错误码编排不利于感性记忆和分类。

    说明:数字是一个整体,每位数字的地位和含义是相同的。
    反例:一个五位数字 12345,第1位是错误等级,第 2 位是错误来源,345 是编号,人的大脑不会主动地分辨每位数字的不同含义。

    《手册》说明了纯数字错误码存在的问题。

    纯字母错误码

    那么纯字母错误码不香吗?有两个问题:

    • 对于使用汉语的我们用英语去准确描述一个错误有时是比较困难的。
    • 纯英文字母的错误码不利于排序。

    错误码尽量有利于不同文化背景的开发者进行交流与代码协作。

    说明:英文单词形式的错误码不利于非英语母语国家(如阿拉伯语、希伯来语、俄罗斯语等)之间的开发者互相协作。

    快速溯源 | 简单易记 | 沟通标准化

    什么是快速溯源?就是一眼看上去就知道哪里出了什么问题。

    李雷负责 A 服务,韩梅梅负责 B 服务。韩梅梅发现服务 B 出现了一个错误码,韩梅梅能够快速定位这是服务 A 的内部业务异常造成的问题,这个时候韩梅梅就可以拿着错误码找到李雷说,"hi,Li Lei,How old are you。(李雷,怎么老是你)"。李雷拿过来错误码一看,内心万马奔腾,一下就能知道这是上游 Polly 负责的应用阿尔法出了错。

    怎么能达到这个效果呢?

    • 首先要有一套标准并且在域内各个业务都在用同样的标准。
    • 其次要求错误码有自我解释的能力是有信息含量的有意义。
    • 最后在域内要传递错误码。

    错误码标准的意义

    开宗明义借用了《手册》对于错误码定义的原则作为错误码规范能够给我们带来的收益。我想再次强调并且试着从反面阐述没有错误码标准会带来的成本。

    错误码是用来做沟通的:系统与系统间的沟通,人与人间的沟通,人与系统间的沟通。

    试想下面这个场景:

    韩梅梅看到一个异常日志其中一个纯数字的错误码。

    韩梅梅需要理解这串数字代表的是什么,它到底是不是一个错误码,经过几秒钟确定下来这是一个错误码,但她不能确定这是不是本系统中错误码,因为在她负责的系统是由韩梅梅、Lucy 和 Lily 三个人共同维护的,每个人都按照自己的理解定义了一套错误码。

    韩梅梅去系统源码中查找这个错误码,但是发现这个错误码并不是本系统的错误码。

    然后再前翻两页后翻两页从日志上下文中确定这是李雷负责系统的错误码,“Li Lie,how old are you?”。

    韩梅梅把错误码甩到李雷脸上,李雷一脸懵逼,这是我的系统的错误码吗?

    李雷也不确定,因为李雷负责的系统是由李雷、林涛和 Jim 维护的,也是三人共同维护的。

    李雷只好打开源码,还真是!

    上边的场景经过了发现-初判断-判断来源-确定来源-沟通-二次判断-二次确认七个步骤。

    希望上边的场景描述能够说明没有统一标准的错误所带来的成本。

    四 面向日志的错误码

    输出到日志的错误码有两个用途:

    • 用来快速溯源找到问题。
    • 用来形成监控大盘。

    错误码设计

    《手册》对于错误码的建议有非常多的可取参考的地方:

    错误码不体现版本号和错误等级信息。

    说明:错误码以不断追加的方式进行兼容。错误等级由日志和错误码本身的释义来决定。

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

    错误码不能直接输出给用户作为提示信息使用。

    说明:堆栈(stack_trace)、错误信息(error_message)、错误码(error_code)、提示信息(user_tip)是一个有效关联并互相转义的和谐整体,但是请勿互相越俎代庖。

    在获取第三方服务错误码时,向上抛出允许本系统转义,由 C 转为 B,并且在错误信息上带上原有的第三方错误码。

    结合错误码设计原则、错误码用途、规约建议,面向服务端日志的错误码应该是如下形式。

    错误码分为一级宏观错误码、二级宏观错误码、三级宏观错误码。

    错误码即人性,感性认知+口口相传,使用纯数字来进行错误码编排不利于感性记忆和分类。
    说明:数字是一个整体,每位数字的地位和含义是相同的。

    反例:一个五位数字 12345,第 1 位是错误等级,第 2 位是错误来源,345 是编号,人的大脑不会主动地分辨每位数字的不同含义。

    按照《手册》的建议设计出的面向日志的错误码定义共十三位(十位有意义,三位连接符),并且应该具有如下分类:

    • 应用标识,表示错误属于哪个应用,三位数字。
    • 功能域标识,表示错误属于应用中的哪个功能模块,三位数字。
    • 错误类型,表示错误属于那种类型,一位字母。
    • 错误编码,错误类型下的具体错误,三位数字。

    image.png

    《手册》还有一条是规定错误码应该如何定义:

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

    说明:错误产生来源分为 A/B/C,A 表示错误来源于用户,比如参数错误,用户安装版本过低,用户支付超时等问题;B 表示错误来源于当前系统,往往是业务逻辑出错,或程序健壮性差等问题;C 表示错误来源于第三方服务,比如 CDN 服务出错,消息投递超时等问题;四位数字编号从 0001 到 9999,大类之间的步长间距预留 100。

    五位错误码的好处是易记,但是对于面向日志的错误码场景利用错误码制作需要分类的业务监控大盘将变得比较困难,比如统计应用 A 的功能 B 的错误出现次数。

    同样在系统间传递这个类型的错误码非常有可能发生错误码冲突。

    当然对于分为四段的错误码同样尤其不好的一面,应用标识和功能域标识需要有专人去管理或者开发一个错误码管理工具,否则时间一长很容易产生定义的混乱形成破窗。

    《手册》对于错误码定义我认为非常适合面向外部传递的错误码。简单、易记、是大家熟悉的错误码样式,并且透出的错误码数量是非常有限的。

    不用枚举定义错误码

    国际化支持是一个不使用枚举定义错误码很重要的理由。

    我们通过 i18n 的支持可以做到错误码、错误状态、错误描述的管理。

    五 面向外部传递的错误码

    面向外部传递的错误码是为了把域内的错误信息传递出去。

    可以让域外系统通过错误码进行错误码进行后续的动作或是中断操作或是记录日志继续执行。

    可以让前端通过错误码给出用户准确的错误提示或者忽略错误进行重试。

    错误码设计

    根据《手册》给出的错误码定义建议设计出的面向外部传递的错误码共五位,并且有如下分类:

    • 错误类型,表示错误来源,一位字母。
    • 错误编码,表示具体错误,四位数字。

    image.png

    错误码的后三位编号与 HTTP 状态码没有任何关系。

    错误码即人性,感性认知+口口相传,使用纯数字来进行错误码编排不利于感性记忆和分类。

    说明:数字是一个整体,每位数字的地位和含义是相同的。
    反例:一个五位数字 12345,第1位是错误等级,第 2 位是错误来源,345 是编号,人的大脑不会主动地分辨每位数字的不同含义。

    下图是《手册》给出的错误码示例:

    image.png

    他山之石

    他山之石不一定能攻玉。

    谷歌 API 错误码定义

    谷歌 API 的错误码定义与 HTTP 状态码有着非常强的联系,并且是一个全数字错误码定义。

    没有明显的错误分类,快速识别和自解释能力比较弱。

    image.png

    腾讯 OpenAPI(文智)错误码定义

    这也是一个全数字的错误码,没有明确的分类字段,纯数字的某一位已看不出明显的分类。

    不利于进行感性记忆。
    image.png

    微博 API 错误码定义

    同样是全数字的错误码定义:

    image.png

    其他建议

    《手册》中有一条建议:

    全部正常,但不得不填充错误码时返回五个零:00000。

    这也是在其他家 API 错误码中能够看到的定义。

    参考

    《阿里巴巴java开发手册》
    《Google API Design Guide 》(https://www.bookstack.cn/books/API-design-guide
    《阿里云-文件存储-错误码》(https://help.aliyun.com/document_detail/62603.html
    《微博开放平台-API-错误码》(https://open.weibo.com/wiki/Help/error
    《腾讯开放平台-错误码》(https://wiki.open.qq.com/wiki/%E9%94%99%E8%AF%AF%E7%A0%81

    原文链接:https://developer.aliyun.com/article/766288?

    版权声明:本文中所有内容均属于阿里云开发者社区所有,任何媒体、网站或个人未经阿里云开发者社区协议授权不得转载、链接、转贴或以其他方式复制发布/发表。申请授权请邮件developerteam@list.alibaba-inc.com,已获得阿里云开发者社区协议授权的媒体、网站,在转载使用时必须注明"稿件来源:阿里云开发者社区,原文作者姓名",违者本社区将依法追究责任。 如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:developer2020@service.aliyun.com 进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
    展开全文
  • IBM MQ错误码大全

    热门讨论 2012-03-21 20:15:00
    MQ错误码大全,希望对您有所帮助(错误码已排序,方便大家查找,使用)。
  • API接口错误码设计最佳实践

    千次阅读 2020-03-12 16:13:28
    服务器接口设计中最重要的环节之一便是接口错误码的定义了,通常情况下服务端会定义一些列错误码用以指示接口调用者或者用户进行正确的操作。例如接口参数确实、参数非法、无权限访问、用户身份认证信息过期等等类似...

    简介

    • 服务器接口设计中最重要的环节之一便是接口错误码的定义了,通常情况下服务端会定义一些列错误码用以指示接口调用者或者用户进行正确的操作。例如接口参数确实、参数非法、无权限访问、用户身份认证信息过期等等类似反馈。

    ** 本文将以错误码的类型、易用性、易读性、简洁性等方面进行讲解,内容有**

    • 接口错误码是用来干嘛的?
    • 接口错误码有哪些类型?
    • 接口错误码的定义方式有哪些?
    • 设计的接口错误码需要具有哪些能力?
    • 设计接口错误码的最佳实践

    原文:地址

    1. 接口错误码是用来干嘛的?

    接口错误码,顾名思义,肯定是调用接口失败后反馈给客户端的信息,一般我们调用第三方的开放接口会看到一些非常规范的错误码定义,如下:

    • 系统错误示例:
    {
    "code": 0x02001023,
    "msg": "应用秘钥错误"
    }
    
    {
    "code": 0x02001111,
    "msg": "系统未知错误,请稍后重试!"
    }
    
    • 复杂错误类型示例:
    {
    "code": 0x02001024,  
    "msg": "请求参数非法",   
    "data": {  
        "subErrors": [  
            {    
                "error": "NotEmpty",   
                "msg": "请求参数name为必填项"   
            },    
            {    
                "error": "NotNull",    
                "msg": "请求参数age为必填项"    
            }    
        ]    
      }
    }
    
    • 其他错误响应示例
    {
    "code": 0x0210ffc1,    
    "subCode": "LoginAccountNotFound",
    "msg": "未找到该账户信息,请核实后再登录!"
    }
    

    通过上面示例的错误码得知,错误码的作用有

    1. 诱导接口调用者使用正确的调用方式
    2. 指示调用方依据不同的错误码做逻辑控制处理
    3. 指示用户,引导用户进行正确的操作
    4. 明确指示服务器接口处理异常信息,便于开发人员及时发现与排查

    所以设计一个好用又方便的错误码体系很重要!

    2. 接口错误码有哪些类型?

    主要分为两大类,系统错误码和业务错误码

    • 系统错误码: 一些通用错误信息的定义,一般用于指示开发者正确的进行接口调用和告知调用者接口服务的状态信息。
    • 业务错误码:根据具体业务流程提示或诱导用户进行正确的操作,如用户登录时,账号密码输入错误,接口错误码和提示信息会引导用户重新检查账号密码的正确性并进行重试。

    3. 接口错误码的定义方式有哪些?

    我们做开发时经常会使用到别人提供的接口,比如百度开放平台、支付宝、微信公众号提供的开放API等等。他们都会提供一些系统错误码说明,常见的形式有:

    1. 一个数字型的code标识

      • 长度可控,且字段值比较短,可节省传输带宽
      • 可读性不高,看到错误码后需要参考文档才能知其含义
      • 一般都会通过数字的范围对code进行分段,用于标识不同子服务、业务等等
    2. 一个字符串code标识

      • 长度会比数值型code长
    • 可读性高,见错误码便知其意
    • 通过业务领域对应的名字来进行描述,例如: 服务名+操作类型+失败原因

    4. 我设计的接口错误码需要具有哪些能力?

    本文所设计的错误码需要兼顾以下几个特点

    • 可读性一定要高
    • 兼容性要好,要能支持常见的两种错误码类型,字符串和数值型都需要提供
    • 易于维护,错误码要便于维护
    • 易用性,错误码的定义要对开发人员友好,最好开发人员不需要关心错误码的值
    • 灵活可控,错误码可以手动指定,也可以自动进行维护,而且支持错误码自动分段和手动分段

    5. 接口错误码的最佳实践

    5. 1 错误码的格式和模式的选择
    • 错误码格式采用如下方式
    {
    "code": 0x0210ffc1,    
    "strCode": "LoginAccountNotFound",
    "msg": "未找到该账户信息,请核实后再登录!",
    "data":{}
    }
    
    • code: Long型错误码
    • strCode: 字符串类型错误码
    • msg: 描述信息
    • data: 正常响应内容,json对象,由具体业务接口进行灵活指定
    • 正常响应结构:
    {
    "code": 0,    
    "data":{}
    }
    
    • 错误响应结构(兼容模式):
    {
    "code": 0x0210ffc1,    
    "strCode": "LoginAccountNotFound",
    "msg": "未找到该账户信息,请核实后再登录!"
    }
    
    • 错误响应结构(数值型模式):
    {
    "code": 0x0210ffc1,    
    "msg": "未找到该账户信息,请核实后再登录!"
    }
    
    • 错误响应结构(字符串型模式):
    {
    "code": "LoginAccountNotFound",    
    "msg": "未找到该账户信息,请核实后再登录!"
    }
    
    5. 2 错误码的定义
    • 系统错误码的定义
     @Getter
     @AllArgsConstructor
     public enum ErrorCodes {
     	SUCCESS(0,"success"),//成功
     	SYSTEM_PARAM_LOST(0x06001000,"接口参数缺失"),
         //... 其他错误码的定义
         ;    
         private Long code;
     	private String msg;
         
     }    
    
    • 业务错误码的定义
     @Getter
     @AllArgsConstructor
     public enum BussinessError {	
     		
     	TEST_EXAMPLE_OLD_ERROR(0x06600001, "test.exampleOldError", "完整错误码示例")//手动指定错误码	
     	,LOGIN_ACCOUNT_NOT_EXISTS("login.accountNotExists", "用户登录账号【%s】不存在")//不指定数值型错误码,将会自动生成
          //... 其他错误码的定义
         ;
     	private Integer code;
     	private String strCode;
     	private String msg;
         private BussinessError(int code,String strCode){
             this.code=code;
     		this.strCode=strCode;		
     	}
     	
     	private BussinessError(String strCode, String msg){
     		this.strCode=strCode;
     		this.msg=msg;
     	}
     	
     	private BussinessError(String strCode){
     		this.strCode=strCode;
     	}
         /**
            * 获取参数化的msg值
         */
         public String getMsgParams(Object ...params){
     		if(this.msg!=null){
     			return String.format(this.msg, params);
     		}
     		return this.msg;
     	}
         
     }
    
    5. 3 业务错误码的自动生成
    • 通过错误码枚举成员字段名的字符串生成唯一标识数值,能有效保证字符串错误码不重复
    /**  
        * Title HashUtil.java  
        * Description  
        * @author danyuan
        * @date Nov 8, 2019
        * @version 1.0.0
        * site: www.danyuanblog.com
    */ 
    package com.danyuanblog.common.util;
    
    public class HashUtil {
    	
    	public static int ELFhash(String str)//思想就是一直杂糅,使字符之间互相影响
    	{
    	    int h = 0x0, g;
    	    for(int i = 0 ; i < str.length() ; i++)
    	    {
    	        h = (h<<4) + str.charAt(i); //h左移4位,当前字符占8位,加到h中进行杂糅
    	        if((g = h & 0xf0000000) != 0) //取h最左四位的值,若均为0,则括号中执行与否没区别,故不执行
    	        {
    	            h ^= g>>24; //用h的最左四位的值对h的右起5~8进行杂糅
    	            h &= ~g;//清空h的最左四位
    	        }
    	    }
    	    return h; //因为每次都清空了最左四位,最后结果最多也就是28位二进制整数,不会超int
    	}
    	
    	public static int limitELFHash(String str , int min, int max)
    	{
    	    int k = ELFhash(str);
    	    k = Math.abs(k - min);
    	    int result = k % (max - min);	
    	    result += min;	    
    	    return result;
    	}
    }
    
    • 指定范围的错误码生成
    /**  
        * Title ErrorCodeUtil.java  
        * Description  错误码工具包
        * @author danyuan
        * @date Nov 8, 2019
        * @version 1.0.0
        * site: www.danyuanblog.com
    */ 
    package com.danyuanblog.common.util;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import lombok.extern.slf4j.Slf4j;
    
    import com.danyuanblog.base.exception.ErrorCodes;
    import com.danyuanblog.common.consts.BussinessErrors;
    import com.danyuanblog.common.exception.ErrorCodeDto;
    
    @Slf4j
    public final class ErrorCodeUtil {
    	private final static HashMap<String, Integer> codeMap = new HashMap<>();
      //定义错误码范围为: 0x02100000 ~ 0x02ffffff
    	private final static Integer MIN_VALUE = 0x02100000;
    	private final static Integer MAX_VALUE = 0x02ffffff;
    	static {
    		//生成错误码映射关系
    		init();
    	}
    	
    	/**
        	 * 初始化错误码映射关系
        	 * 
        	 * @author danyuan
    	 */
    	public static void init(){
    		codeMap.clear();
    		Integer code = 0;
    		for(BussinessErrors error :BussinessErrors.values()){
    			if(error.getOldCode() == null || (error.getOldCode() == 0)){
    				code = HashUtil.limitELFHash(error.name(), ErrorCodeUtil.MIN_VALUE, ErrorCodeUtil.MAX_VALUE);
    			}else{//兼容老版错误码
    				code = error.getOldCode();
    			}			
    			if(codeMap.containsValue(code)){
    				//说明产生了冲突,打印冲突信息
    				log.error("业务错误码HASH值产生了冲突,请更新错误码名字再启动应用,错误码冲突如下:");
    				log.error("存在值: {} = {}", error.name(), code);
    				System.exit(-1);//直接退出应用
    			} else {
    				codeMap.put(error.name(), code);
    				log.info("业务错误码:{} = {}", error.name(), "0x0" + Integer.toHexString(code).toUpperCase());
    			}			
    		}
    	}
    	
    	public static Integer getCode(BussinessErrors error){
    		return codeMap.get(error.name());
    	}
    	
    	/**
        	 * 获取业务错误码集合
        	 * @return
        	 * @author danyuan
    	 */
    	public static List<ErrorCodeDto> getBussinessCodes(){
    		List<ErrorCodeDto> list = new ArrayList<>();
    		ErrorCodeDto dto = null;
    		for(String key : codeMap.keySet()){
    			BussinessErrors error = BussinessErrors.valueOf(key);
    			dto = new ErrorCodeDto();
    			dto.setError(error.getCode())
    				.setMsg(error.getMsg())
    				.setCode(codeMap.get(key))
    				.setHexCode("0x0" + Integer.toHexString(codeMap.get(key)).toUpperCase());
    			
    			list.add(dto);
    		}
    		return list;
    	}
    	
    	/**
        	 * 获取系统错误码集合
        	 * @return
        	 * @author danyuan
    	 */
    	public static List<ErrorCodeDto> getSystemCodes(){
    		List<ErrorCodeDto> list = new ArrayList<>();
    		ErrorCodeDto dto = null;
    		for(ErrorCodes error : ErrorCodes.values()){			
    			dto = new ErrorCodeDto();
    			dto.setError(error.getMsgCode())
    				.setCode(error.getCode())
    				.setHexCode("0x0" + Integer.toHexString(error.getCode()).toUpperCase());
    			
    			list.add(dto);
    		}
    		return list;
    	}
    }
    
    
    • 错误码查询接口
    /**  
    * Title ErrorCodeController.java  
    * Description  
    * @author danyuan
    * @date Nov 19, 2018
    * @version 1.0.0
    * site: www.danyuanblog.com
    */ 
    package com.danyuanblog.api;
    
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import com.danyuanblog.api.impl.response.ErrorCodeListResponse;
    import com.danyuanblog.base.exception.BusinessException;
    import com.danyuanblog.base.exception.ErrorCodes;
    import com.danyuanblog.common.exception.ErrorCodeDto;
    import com.danyuanblog.common.util.ErrorCodeUtil;
    import com.danyuanblog.web.api.DictManager;
    
    import io.swagger.annotations.Api;
    import io.swagger.annotations.ApiOperation;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    
    @RestController
    @Api(tags={"错误码服务模块"},value="相关接口")
    public class ErrorCodeController   {
    	
    	@Autowired
    	private DictManager dictManager;
    	
    	@GetMapping(value="errorCodeList",
    			name="查询错误码列表")
    	@ApiOperation(value="查询错误码列表", notes="查询错误码列表")
    	public ErrorCodeListResponse errorCodeList(
    			) throws BusinessException{
    		List<ErrorCodeDto> systemCodes = ErrorCodeUtil.getSystemCodes();
    		for(ErrorCodeDto error : systemCodes){
    			error.setMsg(dictManager.get(error.getError(),"zh_CN"));			
    		}
    		return new ErrorCodeListResponse().setBussinessErrors(ErrorCodeUtil.getBussinessCodes())
    			.setSystemErrors(systemCodes);
    	}
    
    }
    
    @Data
    @Accessors(chain = true)
    @ApiModel(value="ErrorCodeDto",description="业务错误码参数")
    public class ErrorCodeDto implements Serializable{
    
    	/** 
    	 *serialVersionUID
    	 */
    	private static final long serialVersionUID = 1L;
    	@ApiModelProperty(
    			value="业务错误码字典值",
    			example="user.accountNotFound"
    			)
    	private String error;
    	@ApiModelProperty(
    			value="系统错误码整型值对应的十六进制值",
    			example="0x06002007"
    			)
    	private String hexCode;
    	@ApiModelProperty(
    			value="系统错误码整型值对应的十进制值",
    			example="100671495"
    			)
    	private Integer code;
    	
    	@ApiModelProperty(
    			value="错误描述信息",
    			example="该用户账号未找到!"
    			)
    	private String msg;
    }
    
    @Data
    @Accessors(chain = true)
    @ApiModel(value="ErrorCodeListResponse",description="获取系统错误码信息的返回参数")
    public class ErrorCodeListResponse implements Serializable {
    
    	/** 
    	 *serialVersionUID
    	 */
    	private static final long serialVersionUID = 1L;
    	
    	@ApiModelProperty(
    			value="业务错误列表"
    			)
    	private List<ErrorCodeDto> bussinessErrors;
    	@ApiModelProperty(
    			value="系统错误列表"
    			)
    	private List<ErrorCodeDto> systemErrors;
    }
    

    通过这个接口便可以获取整个服务器提供的所有错误码及其含义说明

    展开全文
  • java api 错误码设计,枚举错误码设计以及请求响应返回错误码的使用,源码及举例 错误码设计 错误码采用枚举实现,错误码从1001开始,主要是不想和http请求状态码重复比如200,404等。错误码数值怎么给,看自己项目需求...

    java api 错误码设计,枚举错误码设计以及请求响应返回错误码的使用,源码及举例

    错误码设计
    错误码采用枚举实现,错误码从1001开始,主要是不想和http请求状态码重复比如200,404等。错误码数值怎么给,看自己项目需求,每个功能模块给留足够的数值,比如我给每个模块的范围是1-99 ,通用错误码范围 1001-1099 , 文件模块错误码范围 1101 - 1199 , 其他模块依此类推.

    ErrorCodeEnum.java

    /**
     * @author
     */
    public enum ErrorCodeEnum {
        SUCCESS("0", "success"),
        FAILED("1", "failed"),
        //...
    
        COMMON_ACCOUNT_ERROR("1001", "账号错误"),
        COMMON_TOKEN_ERROR("1002", "token已过期"),
        COMMON_PARAM_EMPTY("1003", "必选参数为空"),
        COMMON_PARAM_ERROR("1004", "参数格式错误"),
        //...
    
        FILE_NOT_EXIST("1101", "文件不存在"),
        //...
    
        SYSTEM_UNKNOWN_ERROR("-1", "系统繁忙,请稍后再试....");
    
        private String code;
        private String desc;
    
        ErrorCodeEnum(String code, String desc) {
            this.code = code;
            this.desc = desc;
        }
    
        public String getCode() {
            return this.code;
        }
    
        public String getDesc() {
            return desc;
        }
    
        @Override
        public String toString() {
            return "ErrorCodeEnum{" + "code='" + code + '\'' + ", desc='" + desc + '\'' + '}';
        }
    }
    

    上述介绍了错误码的设计,下面结合 响应请求返回数据的结构 举例如何使用。

    返回数据的类

    Resp.java

    import java.io.Serializable;
    import java.util.List;
    
    /**
     * 请求的返回类
     * 
     * @author
     *
     * @param <T>
     */
    public class Resp<T> implements Serializable {
    	private static final long serialVersionUID = 1L;
    
    	private String code;
    	private String desc;
    	private T data;
    	private List<T> dataList;
    
    	public String getCode() {
    		return code;
    	}
    
    	public void setCode(String code) {
    		this.code = code;
    	}
    
    	public String getDesc() {
    		return desc;
    	}
    
    	public void setDesc(String desc) {
    		this.desc = desc;
    	}
    
    	public T getData() {
    		return data;
    	}
    
    	public void setData(T data) {
    		this.data = data;
    	}
    	
    	public List<T> getDataList() {
    		return dataList;
    	}
    	
    	public void setDataList(List<T> dataList) {
    		this.dataList = dataList;
    	}
    
    	private Resp<T> code(String code){
    		this.code = code;
    		return this;
    	}
    
    	private Resp<T> desc(String desc){
    		this.desc = desc;
    		return this;
    	}
    	
    	private Resp<T> data(T data){
    		this.data = data;
    		return this;
    	}
    
    	private Resp<T> dataList(List<T> dataList){
    		this.dataList = dataList;
    		return this;
    	}
    	
    	public Resp<T> success(T data){
    		return code(ErrorCodeEnum.SUCCESS.getCode()).desc(ErrorCodeEnum.SUCCESS.getDesc()).data(data);
    	}
    	
    	public Resp<T> success(List<T> dataList){
    		return code(ErrorCodeEnum.SUCCESS.getCode()).desc(ErrorCodeEnum.SUCCESS.getDesc()).dataList(dataList);
    	}
    
    	public Resp<T> failed(ErrorCodeEnum errorCodeEnum){
    		return code(errorCodeEnum.getCode()).desc(errorCodeEnum.getDesc());
    	}
    }
    
    

    在接口中使用错误码返回伪代码例子

    
    if(参数格式错误){
    	    Resp<String> resp = new Resp<>();
            resp.failed(ErrorCodeEnum.COMMON_PARAM_ERROR);
            System.out.println("resp:"+new Gson().toJson(resp));
            //response(resp);
    }
    
    if(打开的文件不存在){
    	    Resp<String> resp = new Resp<>();
            resp.failed(ErrorCodeEnum.FILE_NOT_EXIST);
            System.out.println("resp:"+new Gson().toJson(resp));
            //response(resp);
    }
    

    输出结果:

    resp:{"code":"1004","desc":"参数格式错误"}
    resp:{"code":"1101","desc":"文件不存在"}
    

    参考:https://my.oschina.net/u/1760791/blog/1842315

    展开全文
  • 1、分为了两个,一个是通讯的,一个是业务的。 2、通讯相当于boolean值,只存成功或者失败,没有详细的分成不同编码,详细信息里显示信息。通讯成功后,再看里面业务的是成功还是失败,失败

    背景:

    在前后端接口设计上,一般会有一个状态码,表示成功或者失败。

    但是一个请求会有两个状态,一个是通讯层面的,200,500,400,404等。一个是业务层面的,自己定义的。在某些场景下可能会混淆。比如请求成功了,但是业务失败了,这个时候对应的code返回什么呢?

    看一下大厂的

    微信的支付接口如下:

    1、分为了两个码,一个是通讯的码,一个是业务的码。

    2、通讯码相当于boolean值,只存成功或者失败,没有详细的分成不同编码,详细信息里显示信息。通讯成功后,再看里面业务的码是成功还是失败,失败的码才有分类,分成不同的码和对应的描述

    3、没有管通讯状态404,估计因为是外部接口,而不是前后端接口

    总结:微信的就是两层,两个字段来判断是否成功,先判断通讯是true还是false,true继续看业务编码是true还是false。

    所以在调用微信支付接口时,需要判断两次,

     

    来看支付宝的:

    1、也是两个码,一个code是网关返回码,一个是业务返回码。都有具体的代码,而不是类似布尔类型。

    2、可以理解为 业务成功就是code 是成功的码,判断一个就行,其他的不是业务的错误因为接口对接碰到的比较多,所以放在了和code同级的(所有接口都是相同的公共错误)。业务错误因为接口太多了,所以写一个大的业务错误而不是把所以的业务错误编码都放到和code同级。

    3、也是没有处理404的情况。

    总结:支付宝的实际是一层,一个字段判断是否成功的编码,如果不是,看看是接口公共错误,还是业务错误,如果是业务错误需要进到下一级的业务编码里去找

     

     

    选择自己的才是合适的,个人总结了下。

    1、因为是前后端分离,肯定是前端判断一个编码来区分是否成功比较好。一个code,成功代表100000, 就表示业务成功了。(通讯成功+业务成功)

    2、其他业务错误编码看业务多少,如果业务少,就直接放到和code同一级。如果业务很多,可以再加一个sub_code区分细节。(对应自己定义的异常类)

    3、因为是前后端分离,所以考虑404等错误,也后端捕获,统一返回json数据(http的通讯状态还是保持不变)。code用通讯码。-----这一条不考虑也行,反正spring boot 默认会跳到一个错误页面。----追加思考,404这种想返回json的处理,和这个错误码不妨到一起,单独搞一个枚举类去处理。混在一起容易乱。

    总结:使用1个code,其中一个码表示成功,其他码表示失败(3类:【对应通讯异常类,主要是用来404等错误转json用】【自定义编码对应业务(例如:用户名不能为空)和自定义异常(例如:数据库访问异常、业务层访问异常)进行编多个码,如果业务多,可以再细分一层,或者把业务和非业务的异常再区分一个类型】【系统异常:代码错误导致或者其他未知异常(在支付宝中对应服务不可用)】)

    
       SUCCESS(10000, "操作成功"),//前端只需要判断是否等于10000,就可以表示是否成功了。(通讯成功加业务成功)
    
        /**
         * 通讯的返回码--对应通讯异常,业务自定义异常不要用这个
         */
        //SUCCESS(200, "操作成功"),//防止前端误解,用10000表示最终成功(包括通讯成功加业务成功),其他就都是错误码(通讯的错误码和业务的错误码)
        //REDIRECT(302, "重定向"),//用不到
        PARAM_ERROR(400, "请求参数错误"),
        UNAUTHORIZED(401, "没有权限"),
        FORBIDDEN(403, "禁止访问"),
        NOT_FOUND(404, "资源不存在"),
        NOT_SUPPORTED(405, "Method Not SUPPORTED"),
        //SERVER_ERROR(500, "系统异常"),//为防止通讯错误码和业务错误码混淆,不用500,用对应的业务错误码。
        ROUTER(700, "路由"),
    
        /**
         * 业务级错误码  对应bussion-exception,自定义的异常
         */
        //110000到119999 为登录模块的异常
        WEB_ERROR(110000, "用户名和密码出错"),
        SERVICE_ERROR(120000, "没有授权"),
    
        DB_ERROR(191000, "数据库访问异常"),
        IO_ERROR(192000, "IO操作异常"),
    
        OTHER_ERROR(900000, "其它错误"),//业务的错误
    
        /**
         * 未知的系统错误 对应Exception 异常 ,可能是代码错误或者其他未知的异常
         */
         SYS_ERROR(999999,"系统异常");

     

    后面的纠结:(后面有在想后端要不要处理接口的404?如何处理?看腾讯的某个接口,要么就是返回json不支持,要么就是返回404,可能页面的前端控制到404页面,接口的就对应的接口数据吧。不管了,反正这么做没错。就这样了。)

     

    后面又想了想,可能不太对,因为我看的大厂的是外部对接接口,不是前后端分离接口。找了一下,截图

    微信的:也是一个字段,使用errorcode,成功的时候就是0,错误的时候是其他码。

     

    支付宝

    在前后端这一块反而是和接口那块反过来了,用一个boolean字段 success,来判断,但是他这个success不知道是不是业务的success,还是只是通讯的success,另外他加了traceid。

    看data里面还有errorCode,推测可能还是用一个字段。如果失败了,再看data里面的errorCode,为啥不直接用一个code,要搞的2个字段呢?可能是业务太多,一个code搞不过来,所以搞两层?不管了,按自己意思来了。就一个code。

    展开全文
  • Linux系统C/C++通用错误码实现模板

    千次阅读 2018-09-01 23:47:25
    公司C++项目初期是安排不同的人编写不的模块,有...错误码大型项目中都会使用到,不同模块虽然有不同的错误返回值,但还是有建立一套基本的错误系统,让大家都遵守。否则,错误码随便定义、使用,重构起来十分麻烦。
  • 使用异常还是错误码

    千次阅读 2019-06-22 18:06:46
    ###使用异常代替错误码 这曾经是个社区争论不休的话题,多数人是选择异常替代错误码的。反对者中,有人认为不应该使用异常去控制程序流程,也有些人认为只有"数据库连不上"这种系统异常才算异常,还有些人认为异常会...
  • java异常和错误码定义规范及其使用

    万次阅读 2019-07-29 18:45:00
    而且到最后你一定会发现,所定义的错误码大部分是业务错误码居多,即该错误码明确代表了一个错误码描述,而这个错误描述是给调用方看的,而系统级别的异常详细信息已经堆栈形式在日志中打印出来了,那不同的错再多...
  • 华为手机应用安装错误码分析汇总

    千次阅读 2021-08-11 16:06:03
    华为手机应用安装错误码分析汇总 在应用开发过程中经常会遇到应用安装失败的问题,今天就给大家分析一下一些华为手机上主要的安装错误码,帮助大家快速的解决应用安装问题。 1.该安装包无效或不完整、该安装包与...
  • 海康威视-网络通讯库错误码

    万次阅读 2020-07-06 16:54:26
    海康威视-网络通讯库错误码 错误类型 错误值 错误信息 NET_DVR_NOERROR 0 没有错误。 NET_DVR_PASSWORD_ERROR 1 ...
  • Modbus功能码/异常功能码/错误码

    千次阅读 2019-12-09 17:14:03
    Modbus协议主要构成是地址/标识,功能,寄存器地址,数据报文等内容。由于modbus协议是请求/应答通信协议,其其中功能主要用于表述该数据报文执行的功能,当服务器对客户机进行响应时,它使用功能域来指示...
  • Mqtt 错误码

    千次阅读 2021-01-20 17:37:56
    6=意外错误 32000=等待来自服务器的响应时超时 32100=已连接客户机 32101=已断开客户机连接 32102=客户机正在断开连接 32103=无法连接至服务器 32104=客户机未连接 32105=指定的 SocketFactory 类型与代理程序 URI ...
  • 系统错误码定义规则

    千次阅读 2018-08-01 14:11:39
    一、定义错误异常类 /** * @author yunpeng.zhao * @version $Id TestException.java, v 0.1 2018-08-01 下午1:51 yunpeng.zhao Exp $$ */ public class TestException extends RuntimeException{ private ...
  • SpringBoot 使用异常自定义错误码

    千次阅读 2018-07-11 16:39:16
     基于此,我们需要在 HTTP 状态码基础上拓展业务错误码; 本文介绍一种基于 SpringBoot 和 Exception 的实现方案。二、实验步骤2.1 生成 SpringBoot 基础项目 SpringBoot 官方提供了初始模...
  • 微服务系统错误码设计

    千次阅读 2019-08-28 14:49:47
    那么错误码能为我们带来什么? 首先,通过错误码我们能识别出系统到底出了什么问题? 其次,通过错误码我们应当能识别出哪个系统出了问题? 再次,通过错误码需要知道对应的定位问题和解决问题的方法。 最后,...
  • 常见错误码及定义

    万次阅读 2018-09-19 12:06:38
    常见错误码及定义   错误码暂定都是5位数字,并配有相应的英文解释 错误码为 0 表示成功,其他都表示错误 错误码按模块按功能场景分级分段,前三位错误码表示模块,第四位表示模块下的功能。举例,商城系统里有...
  • linux错误码大全

    万次阅读 2018-03-28 15:42:45
    转自https://blog.csdn.net/zhangwentaohh/article/details/23602931linux错误码大全查看错误代码errno是调试程序的一个重要方法。当linuc Capi函数发生异常时,一般会将errno变量(需includeerrno.h)赋一个整数值,...
  • 海康威视SDK登录失败,错误码为8

    千次阅读 2020-10-09 16:56:03
    问题背景:调试正常,突然之间啥都没改,一直报8错误。 一试 官网上再次下载最新版本SDK https://open.hikvision.com/download/5cda567cf47ae80dd41a54b3?type=10 HCNetSDK.java版本较多,适合自己的(所调...
  • 约定一套状态
  • 如何设计API返回码(错误码)?

    千次阅读 2020-09-08 14:52:32
    一、前言客户端请求API,通常需要通过返回来判断API返回的结果是否符合预期,以及该如何处理返回的内容等 相信很多同学都吃过返回定义混乱的亏,有的API用返回是int类型,有的是string类型,有的用0表示成功,...
  • 现在错误码是: segfault at bfbdd69b ip 00000000bfbdd69b sp 00007fff77a5f368 error 14 in zero (deleted)[7f65bfbdd000+7a2000] 这是什么原因造成的呢,看到了错误码的定义但还是不太明白 /* * Page ...
  • c++ 错误码

    千次阅读 2018-12-09 22:22:19
    std::error_code 是依赖平台的错误码。每个 std::error_code 对象,保有一个源于操作系统或某些低层接口的错 误码,和一个指向 std::error_category 类型对象的指针。错误码的值在错误类别之间可以不唯一 class ...
  • Google登录错误码

    千次阅读 2019-11-02 17:10:52
    近期,接入google,关于google登录的几个常见错误码记录一下 错误码 错误码12500,问题是后台没有配置好,我遇见的问题是没有配置邮箱,加上邮箱后问题解决 错误码12501,是你本地没有配置好,登录的时候返回信息...
  • 1、curl出错 错误码:60 解决方法:在网上找了方法,在WxPay.Api.php文件中,大概在537、538行 找到以下两行代码: curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,TRUE); curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//...
  • 因为请求是异步的,如果在token未拿到之前,也有请求(假设为a)同时发出,就会出现,登陆成功了,但是a请求因为未携带token,接口返回错误code的时候,触发了response拦截器,再次向微信发起授权。此时,就会出现...
  • 阿里云短信发送回执错误码

    千次阅读 2019-12-16 10:22:25
    错误码归属 错误码 错误信息 操作建议 供应商 -1005 内容含有违禁词 建议修改发送内容 供应商 -185 分组手机号每天限制条数 建议24小时后发送 供应商 -182 内容中超过空格限制 建议修改发送内容 供应商 -...
  • 错误码302重定向问题

    千次阅读 2019-10-28 09:12:15
    错误码302重定向问题 302有可能是自己的服务请求出去被自己的机子重定向了,可以从request里面的location可以看到重定向到哪的url

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,399,400
精华内容 559,760
关键字:

错误码