caivega / ipfslib

Other
2 stars 1 forks source link

[enhancement] - 错误信息整理 #135

Open caivega opened 3 years ago

caivega commented 3 years ago

错误信息文档描述

#### S Success                                     --> 错误信息大类
> Success                                          --> 该大类的简单描述

0 **TesSUCCESS** ``The transaction was applied.``  --> 见下表

注:三部分用不同的方式,兼顾显示效果及程序读取(程序要读取该文档生成相应的源代码,这个格式暂定如此,之前还考虑过JSON,后来想想,JSON格式程序读取是方便了,但是人工维护起来感觉不是很方便

错误代码 错误简码 错误详细信息
0 TesSUCCESS The transaction was applied.

错误信息文档链接

错误信息文档

返回错误信息格式

另外:关于该文档本身及错误信息整理相关的可以在这个issue讨论,关于文档里边不同错误信息内容建议单开单独的issue讨论,更新文档直接在上边链接更新

TODO:

  1. 错误简码大小写统一问题

相关资源:

  1. 错误信息文档转换成代码, 当前支持转换成 jsongolang
foreso-GitHub commented 3 years ago

目前版本v0.5.3-dev-20201216-9f304bafe8618c2609901034a670797ad8962723中,发送交易的复合错误是这样的格式:

{
    "error": "1 errors",
    "id": 6,
    "jsonrpc": "2.0",
    "result": [
        "771AE3F8BE4B4727DB0EB594B3E1F04F4CEA8B99F8FAA1468BE68765282040E0",
        {
            "error": "failed to submit transaction AF823314CF7F58FDFA3635C3473053814C0FE0DD2DC2554802811E8CC46BEA93",
            "message": {
                "engine_result": "tefALREADY",
                "engine_result_code": -198,
                "engine_result_message": "The exact transaction was already in this ledger.",
                "tx_blob": "1200...",
                "tx_json": {

                }
            },
            "status": -278,
            "type": "temINVALID"
        }
    ],
    "status": -278,
    "type": "temINVALID"
}

其实有3组错误信息:

  1. 最外面的:
    "status": -278,
    "type": "temINVALID"
  2. result数组中第二个交易包含了2组错误信息:
            "status": -278,
            "type": "temINVALID"

    和message里面的:

                "engine_result": "tefALREADY",
                "engine_result_code": -198,
                "engine_result_message": "The exact transaction was already in this ledger.",

这是因为jt_sendTransaction方法其实做了2个动作,先signTx,然后发送交易到区块链网络。因为sign的时候没有问题,但在发送时发现这个sequence已经被使用,因此发出了2个错误。

另外,如果jt_sendTransaction的两个交易,如果第二个交易在sign的时候就出错(比如secret错误),这种情况下,第一个交易返回的不是交易hash,而是签名后的signedTx内容,如下:

{
    "error": "1 errors",
    "id": 6,
    "jsonrpc": "2.0",
    "result": [
        "1200002280000000240000000661400000000000000f68400000000000000a7321038d7e30fb992b9bee527295edb946fe9f8a7351a68ad6190a781dd8643872b7ea744630440220281c0f4fc6a1aaacb1fb33f262f5d18cb7eda790dcd4feeea551842d3b0b4e1c02205233c6d5baceecb2f1d0105070d50a1ed5b337c5e8176fe741769825f238e42d811426ee193806b471f9bc44e10811d89cb39aa8f7b783143516971a9e811a3397a1c44b6423d22ce1e773ebf9ea7d146175746f746573743a20746f6b656e2074657374e1f1",
        {
            "error": "Bad Base58 checksum: spxbRB1eW1vAJQo1z7mn3fXpzqa9X1 [9 127 225 126 188 165 3 58 60 187 255 8 134 111 101 199 171 93 116 217 177 12 201 231 168 71 188 20 164 108 177 72] expected [212 85 51 198]",
            "message": {
                "fee": "10",
                "from": "jhYquCX969ir4ks7uoAnEU2UmaycYmZrpu",
                "memos": [
                    "autotest: token test"
                ],
                "sequence": 1,
                "to": "jnq61m48pJHvBrDSqt7hzC14ATfYixh99b",
                "value": "1"
            },
            "status": -278,
            "type": "temINVALID"
        }
    ],
    "status": -278,
    "type": "temINVALID"
}

合理的情况是接口调用中的每个交易,如果出错,应该只有一个错误信息。在上例中,result数组中第二个交易中只保留message里面的engine错误(这是真正的错误)即可。 另外sign成功的交易,无论一起发送的其他交易是否sign能成功,最后应该要发送出去并给出结果,而不是给签名后的signedTx。

东东和我觉得,把jt_sendTransaction改成每次只能发送一个交易可以避免这样的问题。大家讨论哈。

foreso-GitHub commented 3 years ago

这段时间试用了一下新的错误信息,感觉新的格式还是比较合理的,也有了一些新的想法,和东东讨论完善后,在这里提出:

交易类接口目前的返回信息格式:

{
    "error": "1 errors",
    "id": 6,
    "jsonrpc": "2.0",
    "result": [
        "771AE3F8BE4B4727DB0EB594B3E1F04F4CEA8B99F8FAA1468BE68765282040E0",
        {
            "error": "failed to submit transaction AF823314CF7F58FDFA3635C3473053814C0FE0DD2DC2554802811E8CC46BEA93",
            "message": {
                "engine_result": "tefALREADY",
                "engine_result_code": -198,
                "engine_result_message": "The exact transaction was already in this ledger.",
                "tx_blob": "1200...",
                "tx_json": {

                }
            },
            "status": -278,
            "type": "temINVALID"
        }
    ],
    "status": -278,
    "type": "temINVALID"
}

建议变成:

{
    "id": 6,
    "jsonrpc": "2.0",
    "results": [ 
        {
            "tx_hash":"771AE3F8BE4B4727DB0EB594B3E1F04F4CEA8B99F8FAA1468BE68765282040E0"
        },    
        {
            "message": {
                "tx_blob": "1200...",
                "tx_json": {}
            },
            "type": "tefALREADY",
            "status": -198,
            "error": "The exact transaction was already in this ledger."
        }
    ],
    "error_count": 1
}

主要有这样几个变化: 1.最外层一定存在4个属性:id,jsonrpc,results(从result改名过来)和error_count(从error改名过来)。 2.results一定是数组,无论是一次发送一个交易,还是一次发送多个交易,最后所有的结果(包括错误信息)都作为一个result放在results里面。 3.error_count的作用是显示这次调用的交易一共有几个出错,这样app开发就不需要遍历results,马上能知道是否发生过错误(error_count是否为0),有几个错误。 4.如果交易出现错误,一个交易最多只有一个错误信息,因此每个错误只要放在对应的result中即可。目前的返回结果中,最多可以有3组错误信息,其实没有必要。 5.在result中,如果这个result是一个错误,应该有4个属性:type,status,error,message。 6.错误信息应该放在result中,而不是放在message中。原先message中的engine_result移动到result中变成result.type,相应地,engine_result_code对应result.status,engine_result_message对应result.error。 7.如果交易成功,返回的是交易的hash,目前把这个hash的字符串直接放在results里面。建议也改成json格式,这样,一是results里面的result,无论成功还是错误,都是json格式,统一;二是可以增强整个返回结果的可读性。

"771AE3F8BE4B4727DB0EB594B3E1F04F4CEA8B99F8FAA1468BE68765282040E0",

===>

{
    "tx_hash":"771AE3F8BE4B4727DB0EB594B3E1F04F4CEA8B99F8FAA1468BE68765282040E0"
}
foreso-GitHub commented 3 years ago

查询类接口目前的返回信息格式:

查询成功:
{
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
        "balance": {
            "value": "100000000",
            "currency": "SWT",
            "issuer": "jjjjjjjjjjjjjjjjjjjjjhoLvTp"
        }
    }
}
查询失败:
{
    "error": "address is not string",
    "id": 1,
    "jsonrpc": "2.0",
    "result": "",
    "status": -269,
    "type": "temBAD_PARAMETER"
}

建议变成:

查询成功:
{
    "id": 1,
    "jsonrpc": "2.0",
    "results": [
        {
            "balance": {
                "value": "100000000",
                "currency": "SWT",
                "issuer": "jjjjjjjjjjjjjjjjjjjjjhoLvTp"
            }
        }
    ],
    "error_count": 0
}
查询失败:
{
    "id": 6,
    "jsonrpc": "2.0",
    "results": [
        {
            "type": "temBAD_PARAMETER",
            "status": -269,
            "error": "address is not string"
        }
    ],
    "error_count": 1
}

主要的变化就是改成和交易类接口的返回格式一致,最外层一定存在4个属性:id,jsonrpc,results和error_count。 这样的改动有2个主要的考虑因素: 1.虽然目前查询基本都是单个查询,没有一次返回多个查询结果的情况,但还是建议把查询结果的格式改得和和交易类接口的返回格式一致。这样对app开发来说只需要写一套代码就能对应所有接口的结果。 2.如果以后有客户需求,需要增加批处理查询功能,那目前的这套结果格式已经能满足要求,无需大改。

foreso-GitHub commented 3 years ago
  1. 类似查询结果直接是非json格式的,建议也都改成json格式,原因同这条一样:

7.如果交易成功,返回的是交易的hash,目前把这个hash的字符串直接放在results里面。建议也改成json格式,这样,一是results里面的result,无论成功还是错误,都是json格式,统一;二是可以增强整个返回结果的可读性。

目前的格式:

{
    "id": 1,
    "jsonrpc": "2.0",
    "result": "v0.5.3-dev-20201216-be83b3f3cf9773881eb5fcf277e9b9afe8caaa8c"
}

建议改成:

{
    "id": 1,
    "jsonrpc": "2.0",
    "results": [
        {
            "version":  "v0.5.3-dev-20201216-be83b3f3cf9773881eb5fcf277e9b9afe8caaa8c"
        }
    ],
    "error_count": 0
}
caivega commented 3 years ago

目前版本v0.5.3-dev-20201216-9f304bafe8618c2609901034a670797ad8962723中,发送交易的复合错误是这样的格式:

{
    "error": "1 errors",
    "id": 6,
    "jsonrpc": "2.0",
    "result": [
        "771AE3F8BE4B4727DB0EB594B3E1F04F4CEA8B99F8FAA1468BE68765282040E0",
        {
            "error": "failed to submit transaction AF823314CF7F58FDFA3635C3473053814C0FE0DD2DC2554802811E8CC46BEA93",
            "message": {
                "engine_result": "tefALREADY",
                "engine_result_code": -198,
                "engine_result_message": "The exact transaction was already in this ledger.",
                "tx_blob": "1200...",
                "tx_json": {

                }
            },
            "status": -278,
            "type": "temINVALID"
        }
    ],
    "status": -278,
    "type": "temINVALID"
}

其实有3组错误信息:

  1. 最外面的:
    "status": -278,
    "type": "temINVALID"
  1. result数组中第二个交易包含了2组错误信息:
            "status": -278,
            "type": "temINVALID"

和message里面的:

                "engine_result": "tefALREADY",
                "engine_result_code": -198,
                "engine_result_message": "The exact transaction was already in this ledger.",

这是因为jt_sendTransaction方法其实做了2个动作,先signTx,然后发送交易到区块链网络。因为sign的时候没有问题,但在发送时发现这个sequence已经被使用,因此发出了2个错误。

另外,如果jt_sendTransaction的两个交易,如果第二个交易在sign的时候就出错(比如secret错误),这种情况下,第一个交易返回的不是交易hash,而是签名后的signedTx内容,如下:

{
    "error": "1 errors",
    "id": 6,
    "jsonrpc": "2.0",
    "result": [
        "1200002280000000240000000661400000000000000f68400000000000000a7321038d7e30fb992b9bee527295edb946fe9f8a7351a68ad6190a781dd8643872b7ea744630440220281c0f4fc6a1aaacb1fb33f262f5d18cb7eda790dcd4feeea551842d3b0b4e1c02205233c6d5baceecb2f1d0105070d50a1ed5b337c5e8176fe741769825f238e42d811426ee193806b471f9bc44e10811d89cb39aa8f7b783143516971a9e811a3397a1c44b6423d22ce1e773ebf9ea7d146175746f746573743a20746f6b656e2074657374e1f1",
        {
            "error": "Bad Base58 checksum: spxbRB1eW1vAJQo1z7mn3fXpzqa9X1 [9 127 225 126 188 165 3 58 60 187 255 8 134 111 101 199 171 93 116 217 177 12 201 231 168 71 188 20 164 108 177 72] expected [212 85 51 198]",
            "message": {
                "fee": "10",
                "from": "jhYquCX969ir4ks7uoAnEU2UmaycYmZrpu",
                "memos": [
                    "autotest: token test"
                ],
                "sequence": 1,
                "to": "jnq61m48pJHvBrDSqt7hzC14ATfYixh99b",
                "value": "1"
            },
            "status": -278,
            "type": "temINVALID"
        }
    ],
    "status": -278,
    "type": "temINVALID"
}

合理的情况是接口调用中的每个交易,如果出错,应该只有一个错误信息。在上例中,result数组中第二个交易中只保留message里面的engine错误(这是真正的错误)即可。 另外sign成功的交易,无论一起发送的其他交易是否sign能成功,最后应该要发送出去并给出结果,而不是给签名后的signedTx。

东东和我觉得,把jt_sendTransaction改成每次只能发送一个交易可以避免这样的问题。大家讨论哈。

里边第三层错误,实际上是以前老版本的交易错误返回格式,这两天更新的版本,已经把这个去掉了,只有我们现在试用的错误格式样子,交易相关的rpc是链主要的功能接口,增加一次提交多条,主要是为了提交处理效率考虑。。。现在有四个接口支持一次提交多条的,即jt_sign, jt_signTransaction, jt_sendRawTransaction, jt_sendTransaction, 除去jt_sign很少用,剩下三个,jt_sendTransaction = jt_signTransaction + jt_sendRawTransaction, jt_signTransaction及jt_sendRawTransaction已经支持一次提交多条,如果jt_sendTransaction不支持一次提交多条的话,一个不统一,虽然实际使用中节点的jt_sendTransaction, 包括jt_signTransaction都很少用,另外一个就是实际上也增加了后台实现的复杂度

caivega commented 3 years ago

这段时间试用了一下新的错误信息,感觉新的格式还是比较合理的,也有了一些新的想法,和东东讨论完善后,在这里提出:

交易类接口目前的返回信息格式:

{
    "error": "1 errors",
    "id": 6,
    "jsonrpc": "2.0",
    "result": [
        "771AE3F8BE4B4727DB0EB594B3E1F04F4CEA8B99F8FAA1468BE68765282040E0",
        {
            "error": "failed to submit transaction AF823314CF7F58FDFA3635C3473053814C0FE0DD2DC2554802811E8CC46BEA93",
            "message": {
                "engine_result": "tefALREADY",
                "engine_result_code": -198,
                "engine_result_message": "The exact transaction was already in this ledger.",
                "tx_blob": "1200...",
                "tx_json": {

                }
            },
            "status": -278,
            "type": "temINVALID"
        }
    ],
    "status": -278,
    "type": "temINVALID"
}

建议变成:

{
    "id": 6,
    "jsonrpc": "2.0",
    "results": [ 
        {
          "tx_hash":"771AE3F8BE4B4727DB0EB594B3E1F04F4CEA8B99F8FAA1468BE68765282040E0"
        },    
        {
            "message": {
                "tx_blob": "1200...",
                "tx_json": {}
            },
            "type": "tefALREADY",
            "status": -198,
            "error": "The exact transaction was already in this ledger."
        }
    ],
    "error_count": 1
}

主要有这样几个变化: 1.最外层一定存在4个属性:id,jsonrpc,results(从result改名过来)和error_count(从error改名过来)。 2.results一定是数组,无论是一次发送一个交易,还是一次发送多个交易,最后所有的结果(包括错误信息)都作为一个result放在results里面。 3.error_count的作用是显示这次调用的交易一共有几个出错,这样app开发就不需要遍历results,马上能知道是否发生过错误(error_count是否为0),有几个错误。 4.如果交易出现错误,一个交易最多只有一个错误信息,因此每个错误只要放在对应的result中即可。目前的返回结果中,最多可以有3组错误信息,其实没有必要。 5.在result中,如果这个result是一个错误,应该有4个属性:type,status,error,message。 6.错误信息应该放在result中,而不是放在message中。原先message中的engine_result移动到result中变成result.type,相应地,engine_result_code对应result.status,engine_result_message对应result.error。 7.如果交易成功,返回的是交易的hash,目前把这个hash的字符串直接放在results里面。建议也改成json格式,这样,一是results里面的result,无论成功还是错误,都是json格式,统一;二是可以增强整个返回结果的可读性。

"771AE3F8BE4B4727DB0EB594B3E1F04F4CEA8B99F8FAA1468BE68765282040E0",

===>

{
  "tx_hash":"771AE3F8BE4B4727DB0EB594B3E1F04F4CEA8B99F8FAA1468BE68765282040E0"
}

这个问题,之前讨论的时候就提到,就是正确结果与错误结果在一起的时候,如果分辨问题,我现在只能通过反射判断item类型来分辨了,这个实际上还是不方便

根据引用的提到的,与其用tx_json, 不如与外边格式一致

正确的结果,

{
“result”: "771AE3F8BE4B4727DB0EB594B3E1F04F4CEA8B99F8FAA1468BE68765282040E0"
}

错误的结果是:

{
    "message": {
        "tx_blob": "1200...",
        "tx_json": {}
    },
    "type": "tefALREADY",
    "status": -198,
    "error": "The exact transaction was already in this ledger."
}

这样的好处是,与外边的格式统一,判断方式与使用方式也统一,唯一不好的,就是正确结果,取的时候比以前麻烦些,以前直接是一个string类型,现在是一个object类型

caivega commented 3 years ago

查询类接口目前的返回信息格式:

查询成功:
{
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
        "balance": {
            "value": "100000000",
            "currency": "SWT",
            "issuer": "jjjjjjjjjjjjjjjjjjjjjhoLvTp"
        }
    }
}
查询失败:
{
    "error": "address is not string",
    "id": 1,
    "jsonrpc": "2.0",
    "result": "",
    "status": -269,
    "type": "temBAD_PARAMETER"
}

建议变成:

查询成功:
{
    "id": 1,
    "jsonrpc": "2.0",
    "results": [
        {
            "balance": {
                "value": "100000000",
                "currency": "SWT",
                "issuer": "jjjjjjjjjjjjjjjjjjjjjhoLvTp"
            }
        }
    ],
    "error_count": 0
}
查询失败:
{
    "id": 6,
    "jsonrpc": "2.0",
    "results": [
        {
            "type": "temBAD_PARAMETER",
            "status": -269,
            "error": "address is not string"
        }
    ],
    "error_count": 1
}

主要的变化就是改成和交易类接口的返回格式一致,最外层一定存在4个属性:id,jsonrpc,results和error_count。 这样的改动有2个主要的考虑因素: 1.虽然目前查询基本都是单个查询,没有一次返回多个查询结果的情况,但还是建议把查询结果的格式改得和和交易类接口的返回格式一致。这样对app开发来说只需要写一套代码就能对应所有接口的结果。 2.如果以后有客户需求,需要增加批处理查询功能,那目前的这套结果格式已经能满足要求,无需大改。

现在通过status或者type是可以判断出是否出错,以及出了啥错,这个现在是没问题了,你这个里边提到了一个很重要的问题,就是与错误相关的一些参数信息,除了你说的error_count这个错误参数没地方放,实际上还有一类信息,就是错误关联的对象,比如同样是BAD_PARAMETER, 可能是 请求参数中“from”出的错,也可能是请求参数"to"出的错,如果BAD_PARAMETER,from有一个,比如叫BAD_FROM_PARAMETER, to有一个,比如叫BAD_TO_PARAMETER, 这样的话,错误列表会很膨胀,没有很好的结构化,最后太多以致于没有办法维护,不行我们可以把message的具体格式再考虑考虑??

结论是,现在的错误格式,没有考虑,错误参数及错误关联对象返回的地方

另外后续加批量调用的功能,这个因为这套rpc参考以太的,以太现在已经支持了,只需要把现在每个rpc的参数,再放到一个数组中即可,这个是可嵌套的

foreso-GitHub commented 3 years ago

最后大家确定的格式如下:

{
    "id": 1,
    "jsonrpc": "2.0",
    "error":{
        "description":"compound errors",
        "count":1
    },
    "result": [
        {
            "result":"771AE3F8BE4B4727DB0EB594B3E1F04F4CEA8B99F8FAA1468BE68765282040E0"
        }, 
        {
            "error": {
                "description":"invalid transaction flags",
                "information":"from is invalid",
                "message": {
                    "decimals": "8",
                    "flags": 1,
                    "from": "jsTL48gDwm5DwBvWRXSCpB6CtwJzAnQC1f",
                    "local": false,
                    "name": "TestCoin_StrangeName",
                    "symbol": "15fd23aef27",
                    "total_supply": "10000",
                    "type": "IssueCoin"
                }
            },            
            "status": -278,
            "type": "temINVALID"
        }
    ],
    "status": 1000,
    "type": "tecCOMPOUND"
}

注意:

  1. 有2个地方会返回错误信息(error,status,type): 1.1 返回的response的object保留最外层的错误信息,比如上例中的 "status": 1000,"type": "tecCOMPOUND" 1.2 result的object中的错误信息,比如上例中的 "status": -278,"type": "temINVALID"
  2. error改成object,里面有 2.1 description,用于描述type具体的内容,该内容固定,和type一致 2.2 information,用于描述出错的交易的具体出错信息,比如是from地址不合法等 2.3 message,存放和交易相关的信息 2.4 count,显示本次结果中有多少个错误 2.5 以后还可以扩展其他和错误有关的内容
  3. 成功的结果也改成object,内容名称为“result”
foreso-GitHub commented 3 years ago

关于查询接口,大家同意也要支持批处理查询,但12月的提交版不考虑这个功能,因为变化会比较大,会在后面的版本支持。 好处:

  1. 和交易结果统一
  2. 有更好的扩展性

查询接口修改后的返回结果:

查询成功:
{
    "id": 1,
    "jsonrpc": "2.0",
    "result": [
        {
                "value": "100000000",
                "currency": "SWT",
                "issuer": "jjjjjjjjjjjjjjjjjjjjjhoLvTp"
         }
    ]
}
查询失败:
{
    "id": 6,
    "jsonrpc": "2.0",
    "result": [
        {
            "type": "temBAD_PARAMETER",
            "status": -269,
            "error": "address is not string"
        }
    ]
}

具体细节后面还需要继续讨论。

caivega commented 3 years ago

最新的返回格式里边,这两个词用了缩写

"description" => "desc" "information" => "info"