[Bug] dsh web process crashes with uncaught ENOENT when a subprocess spill temp dir disappears
#5250
yuhanwanli99-cpu
started this conversation in
General
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
问题概述 dsh web 服务器进程会整体崩溃:当子进程输出溢出的 spill 临时目录被删除时,openSync 抛出的 ENOENT 成为未捕获异常,直接杀掉整个 Node 进程。全新启动即可复现。
版本
dsh/CLI:0.1.1-rc.2(当前 master 与 v0.1.2-alpha.3 同样存在)
Node:v22.23.2(Linux,容器化宿主,/tmp 会被周期性清理)
崩溃堆栈
Error: ENOENT: no such file or directory, open '/tmp/dsh-subprocess-TM9I5B/dsh-subprocess-67-3-9134bc97f1ff-stdout.log'
at OutputCollector.spillAll (packages/subprocess/subprocess-local/lib/index.js:666)
at OutputCollector.push (...:642)
at Socket. (...:811)
(完整堆栈见下)
根因 packages/subprocess/subprocess-local/src/spawn.ts 中,spill 目录每个进程只建一次并缓存;当某个子进程流超过内存上限时,OutputCollector.spillAll 打开 spill 文件,但完全没有错误处理;调用点是裸的 stream.on('data', ...) 回调。因此一旦进程存活期间 /tmp/dsh-subprocess-XXXX 被外部清理(tmp 清理器 / 容器重置 /tmp),openSync 抛出的 uncaught exception 会从 socket 回调冒出去,直接把整个进程 abort。
补充:dsh 装了 unhandledRejection 守卫(installFailLoud),但没有 uncaughtException 守卫,所以事件回调里同步抛出的 FS 异常是致命的。
影响
任何 /tmp/dsh-subprocess-* 可能被删除的环境(容器、带 tmp 清理器的宿主)都会崩掉整个 dsh web。
会话日志不会记录错误,只由崩溃恢复合成 { kind: 'interrupted' }。
非 OOM、非模型/网关错误、非原生模块 segfault——纯粹是"被清掉的临时目录"这条错误路径没做容错。
修复建议
spillAll 的 openSync/writeSync 包 try/catch,失败时降级为纯内存收集(spillDisabled = true),或重建目录。
可选:加全局 uncaughtException 守卫,让同步异常只记日志而不是 abort。
可选:spill 目录按需重建,或校验其仍存在。
All reactions