使用nodemon搭建服务器时出现unhandled 'err' event报错如何处理?
错误根因
你遇到的ERR_STREAM_WRITE_AFTER_END属于Node.js HTTP服务常见错误,触发原因是:同一个HTTP响应对象ServerResponse在已经调用res.end()结束响应流之后,又被执行了写入内容、再次调用res.end()的操作,HTTP响应流是单次可读的,关闭后无法再写入内容,所以会抛出未捕获错误导致服务崩溃。
排查步骤
- 首先定位报错位置:日志已经明确指向你的
app.js文件第17行,此处代码为res.end()调用,向上回溯逻辑,确认是否在本次请求的处理流程中,已经提前调用过res.end()/res.send()等结束响应的方法。 - 常见错误写法如下,可对照检查:
// 错误示例:路由判断未加return,命中第一个分支后仍会执行后续的res操作 const http = require('http') const server = http.createServer((req, res) => { if (req.url === '/') { res.end('首页内容') } // 访问首页时,上面已经结束响应,此处仍会执行,触发报错 if (req.url === '/about') { res.end('关于页内容') } res.end('404') })
修复方案
永久修复
给所有res.end()调用前添加return,确保响应结束后终止后续代码执行,修复后的示例代码:
const http = require('http') const server = http.createServer((req, res) => { if (req.url === '/') { return res.end('首页内容') } if (req.url === '/about') { return res.end('关于页内容') } return res.end('404') })
同时检查所有异步逻辑,确保res.end()只在所有异步操作完成后调用1次,不要出现同步先结束响应、异步回调再操作响应的情况。
临时应急方案
如果暂时无法定位到重复调用的位置,可以给响应对象添加错误事件监听,捕获该错误避免服务直接崩溃:
const server = http.createServer((req, res) => { // 捕获响应流错误,避免服务退出 res.on('error', (err) => { if (err.code === 'ERR_STREAM_WRITE_AFTER_END') { console.log('忽略重复写入响应错误') } }) // 原有业务逻辑 })
内容的提问来源于stack exchange,提问作者sujalbarsaiyan
相关产品推荐
相关产品推荐

