Closed tzwm closed 1 year ago
呃另外我不太会 JS,这个上传脚本是 ChatGPT 帮忙写的,但我大致看了下没啥毛病,出错的地方在 larkclient API 调用上,其他逻辑看起来没问题。
厉害呀同学,ChatGPT可以的。
我试了一下正常的调用链路是可以的:
可以先试试发送单个图片看看?排除下文件本身的原因
LTS 版本18.15.0 的 Node.js 调用 im.image.create
方法会有问题,报错基本一致;切到版本 16.20.0 就没有问题。
[
[
TypeError: source.on is not a function
at DelayedStream.create (/xxx/node_modules/.pnpm/delayed-stream@1.0.0/node_modules/delayed-stream/lib/delayed_stream.js:33:10)
at CombinedStream.append (/xxx/node_modules/.pnpm/combined-stream@1.0.8/node_modules/combined-stream/lib/combined_stream.js:45:37)
at FormData.append (/xxx/node_modules/.pnpm/form-data@4.0.0/node_modules/form-data/lib/form_data.js:75:3)
at build (/xxx/node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/helpers/toFormData.js:63:16)
at each (/xxx/node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/helpers/toFormData.js:58:9)
at Object.forEach (/xxx/node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/utils.js:276:12)
at build (/xxx/node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/helpers/toFormData.js:40:13)
at toFormData (/xxx/node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/helpers/toFormData.js:67:3)
at Object.transformRequest (/xxx/node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/defaults/index.js:80:14)
at transform (/xxx/node_modules/.pnpm/axios@0.27.2/node_modules/axios/lib/core/transformData.js:18:15)
]
]
在 Node 16 里,CombinedStream.append
调用传进来的数据是一个 Buffer
:
但是在 Node 18 里,CombinedStream.append
调用传进来的数据是一个 Blob
:
CombinedStream.isStreamLike
这个方法显然没有考虑 Blob 这种情况,显而易见的就把 Blob
当作 Stream
交给了 DelayedStream.create
处理,结果调用了不存在的 on
方法,报错。
接下来找找根本原因。
在 Nodejs 16 中,追踪整个调用栈上的参数类型,在 build
之前都是 Uint8Array
,build
之后都是 Buffer
,看起来没什么问题。
那问题应该与 build
方法有关,我们检查下 build
的逻辑。
convertValue
中有转换类型的逻辑,在 formData.append
入参中,类型已经从 Uint8Array
转为了 Buffer
,我们检查下逻辑:
哦吼,看到问题了,Nodejs 16 中没有 Blob
这种类型,所以用的是 Buffer
来承载数据;但是 Nodejs 18 中有了 Blob
就会优先使用 Blob
类型;刚好碰到一个类型校验不严谨的(笑),就搞了个 bug。
在聊解决方案之前,让我先吐槽下这个类型断言逻辑,这种逻辑是哪个天才想出来的,不是 Buffer 就是 Stream?这不是妥妥的瞧不起 null 和 undefined 一大家子吗?
我扔个 global 进去都能搞崩(笑)。
正确的处理逻辑应当使用 instanceof ReadStream
或者 instanceof Stream
方式,起码逻辑应该是:我认出来你是 Stream,你才是 Stream,否则我就不支持。
有两个方案解决:
Blob
特性的低版本,或者在全局干掉 Blob
对象(有风险)combined-stream@1.0.8
版本的同名包给替换掉,这玩意已经好几年没更新了,别指望作者能修问题上述建议仅供参考,如有问题欢迎指出。
感谢同学提供思路,我这边看下尽快修复
1.17.1版本以上可以使用stream代替buffer,1.17.1以下版本需要对image字段ts-ignore一下:
const file = fs.createReadStream('your url');
client.im.image.create({
data: {
image_type: 'message',
image: file
}
}).then(res => {
console.log(res);
}).catch(e => {
console.log(e);
});
写了个简单的图片批量上传脚本, 有比较奇怪的错误,想要求助一下。 client 其他的消息发送指令都正常使用没问题,就是图片上传这个有点异常。
@larksuiteoapi/node-sdk 版本
1.12.0
。