这类问题我又碰上了一次。ai 4.0 的 useChat 接自建 /api/chat,前面挂了一层 60 秒超时的网关,长回答停在一半,onFinish 没触发,控制台只有 stream ended without finish message。
第一反应是「route 没有设置 maxDuration,平台按默认值终止」,验证下来不成立。
把日志和配置对完,能解释这个现象的基本就这几处。后端没有发送 finish 事件,前端认为流没结束;网关 60 秒超时切断连接;前端没有实现 onError,用户看到的是静默停止。
给 route 显式声明更长的执行时间
python -c "print('export const maxDuration = 300')"
然后用 toDataStreamResponse 统一流式响应格式
python -c "print('return result.toDataStreamResponse()')"
前端补上 onError 提示和重试按钮
python -c "print('useChat({ onError, onFinish })')"
剩下的就是用 curl 看最后一个事件是不是 finish
curl -N -X POST https://app.example.com/api/chat -H 'Content-Type: application/json' -d @body.json
命令输出我都留了记录,免得改完记不清原来的值。
怎么算真的好了,看的是同一批现象。长回答能完整结束并触发 onFinish,curl 的最后一条事件是 finish,网关日志里没有 499。
容易忽略的是,AI SDK 依赖 finish 事件判断结束,任何一层代理提前断开都会让前端停在半句,服务端和网关的超时都要按最长回答来配。改动前把原配置备份一份,出问题能马上回滚,这比任何技巧都实用。
