Skip to content

简单bug: data.data.errno, "Cannot read properties of undefined" #2910

@HikerX

Description

@HikerX

Qinglong version

v2.20.1

Steps to reproduce

在 sample/notify.js 中,关于server酱通道serverNotify方法 第304行,有一个 data.data.errno 引用。
if (data.errno === 0 || data.data.errno === 0) {
这里data预期是res body, JSON对象。 原文确有注释解释这么写的目的。

“// server酱和Server酱·Turbo版的返回json格式不太一样”

问题是,当使用server酱(常规版)时,在超次数请求后,得到的res body结构如下,

{"message":"[AUTH]超过当天的发送次数限制,请稍后再试","code":40001,"info":"超过当天的发送次数限制,请稍后再试","args":[null],"scode":471}

可以发现,这时 if 语句中 data.errno 和 data.data 的值都是 undefined. 那么,执行到 data.data.errno 时,自然会抛出一个异常 "Cannot read properties of undefined"。

What is expected?

这个异常,不决定通知实际成败与否,随后就会被catch。不过,会在日志里打印出一段冗长文字,而且会隐藏包含data中真正发送通知失败的原因。

期望:不抛出异常,继续 else逻辑,简单打印 data。

What is actually happening?

原语句没有适配json结果没有data字段时的情形。

当然,就算json中有data字段,值也可能为null, data.data.errno 仍然是危险引用。

可以简单修改,先行判断 data.data 的值,
if (data.errno === 0 || data.data && data.data.errno === 0) {

也可以优雅一点,使用 可选链运算符(?.)

if (data.errno === 0 || data.data?.errno === 0) {

?. 运算符与 . 链式运算符相似,不同之处在于,如果引用是空值(null 或 undefined),它不会导致错误,而是使表达式短路并返回 undefined。

补充

  • 已知一,server酱(常规版)发送通知成功时,返回的json结构如下
    { code: 0, message: '', data: { pushid: '239***', readkey: 'SCT******', error: 'SUCCESS', errno: 0 } }
    可以看到,这时 data.data.errno 字段确实非空。
    同时注意,最外层有 data.code 字段可视作状态码;并且,从前面知道,在发送失败时返回的 json 中,仍然有 data.code 字段,却没有了 data.data.errno 字段。
    显然,使用 data.code 字段代替data.data.errno 字段作状态码是更优选择。

  • 已知二,在python版 sample/notify.py 第336行,同一接口,没有引用data.data.errno字段。
    if response.get("errno") == 0 or response.get("code") == 0:

由于不能测试turbo版,不能直接确定其返回json结构。猜测,data.errno 字段是被 turbo版使用。

综上,合理的修改是
if (data.errno === 0 || data.code === 0) {

System Info

Any additional comments?

No response

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions