乐于分享
好东西不私藏

用 AI 做个旅行规划工具:AI 喊冤喊出了一个高德的 Bug

用 AI 做个旅行规划工具:AI 喊冤喊出了一个高德的 Bug

这是【用 AI 做个旅行规划工具】系列文章的第 21 篇。

接上回。上篇文章我让 AI 写了一份检讨书里,我们提到「更坑的是 SDK,既不调用户 callback 也不报 error,直接吞掉了异常」。这篇文章我们来深入看一下具体的问题。

AI 自己叫冤

我们之所以能找到这里,是因为当时我 PUA AI 时,我发现它在小声为自己喊冤:

好像在说,SDK 的问题怪我干嘛?

那个异常的 JSONP 响应是这样的:

HTTP 200,脚本正常执行。高德服务端返回了明确的错误码和错误描述。但 getLocation 的 callback 没被调用。

找出 Bug

然后我就让 AI 找找更根本的原因。

高德 JS API 是闭源的,从 CDN 拉下来的 bundle 是 minified JavaScript,但足够 AI 理解逻辑了。

我们本来以为应该是这样的:

getLocation(address, callback)  → 发出 JSONP 请求    → 请求成功? → 调 callback("complete", result)    → 请求失败? → 调 callback("error", result)

但 SDK 实际是这样写的:

getLocation(address, callback)  → 发出 JSONP 请求    → 请求成功而且数据正常? → 调 callback("complete", result)    → 请求失败? → 调 callback("error", result)

看出差异在哪了吗?第一个判断条件多了个“而且”。

// AI 从 minified bundle 还原出来的关键逻辑WebService.get(url, params, (status, result) => {  if (status === "complete" && result.status === "1") {    _geocodingComplete(result, cb);  // ← 只有两个条件同时满足才进  } else if (status === "error") {    _onError(result, cb);            // ← JSONP 加载失败走这里  }  // complete 但 result.status 不是 "1" → 什么都不会发生});

官方文档怎么说?

我去翻了高德 JS API 的文档。

文档其实说得不是很清楚:

不过也说了 result 有可能是错误信息。

另外示例代码上也是按这个逻辑来写的。

文档和示例代码给人的感觉是 callback 始终会被调到。可是源码里却留了这么个“逻辑漏洞”。

社区有人提过吗?

我让 AI 搜了一圈,也发现有一些遇到“Geocoder 无回调”的,但几乎都被归因到插件没加载、Key 配置不对、并发太高等原因。

建议也都是降 QPS、加缓存、用 batch 之类的。

没有人追到源码里指出: JSONP 200 + body status:0 的时候,SDK 不会调你的 callback。

给高德提个 bug report

既然发现了是 SDK 的问题,我决定给高德提个工单。

我把详细信息提交上去,第二天高德就回复了:

您好,非常感谢您的反馈,经核实,geocoder.getLocation 不返回错误回调是个bug,正在排期修复阶段。给您带来不便深感歉意。

目前您也可以先封装web服务提供的地理编码接口使用,接口文档:https://lbs.amap.com/api/webservice/guide/api/georegeo#s3

不得不说,回复效率还是挺高的。给高德工程师点个赞👍。

尾声

从翻 Network 面板发现异常响应,到读 bundle 源码确认逻辑,到查文档对账、搜社区验证,最后提工单、收到高德确认。一个“地图点位为什么消失”的问题,终于可以划上句号了。

也算没白折腾。

欢迎关注,期待下次见面