node.js - 节点 try/catch 块仍然冒泡
问题描述
我在捕获服务器渲染错误时遇到问题,对我来说奇怪的是它到达了 catch 语句,但它仍然冒泡并崩溃并获得未捕获的异常。
这是我的功能的剥离版本:
export default (htmlFilePath, observer) => async (req, res) => {
try {
const { state } = await rehydrate.dispatchRequired(store, [
setMobileDetect.bind(null, mobileDetect),
...REQUIRED_ACTIONS,
]);
// Will dispatch the required data through the store,
// the returned value is not important
const matches = rehydrate.getMatches(req, state);
let status = 200;
componentNames = matches.map(
({ route }) => route.component.displayName,
);
await rehydrate.rehydrate(matches, store, state);
const markupStream = renderToNodeStream(
<Provider store={store}>
<ConnectedRouter history={history} location={context}>
<App />
</ConnectedRouter>
</Provider>,
);
if (context.url) {
return res.redirect(301, context.url);
}
// if no routes match we return 404
if (!matches.length) {
status = 404;
}
return fs
.createReadStream(htmlFilePath)
.pipe(htmlReplace("#root", markupStream))
.pipe(
replaceStream("__SERVER_DATA__", serialize(store.getState())),
)
.pipe(res.status(status));
} catch (err) {
const errMarkup = renderToNodeStream(
<Provider store={store}>
<ConnectedRouter history={history} location={context}>
<Error500 error={err} />
</ConnectedRouter>
</Provider>,
);
logger.log({
level: "error",
message: `Rendering ${
req.originalUrl
} fallback to Error render method`,
...{
errorMessage: err.message,
stack: err.stack,
},
});
return fs
.createReadStream(htmlFilePath)
.pipe(htmlReplace("#root", errMarkup))
.pipe(res.status(500));
} finally {
logger.info(
`Request finished ${req.originalUrl} :: ${res.statusCode}`,
);
end({
route: path,
componentName: componentNames[0],
code: res.statusCode,
});
logger.profile(profileMsg);
}
};
我希望我的 catch 块返回 500 个错误的模块,但节点实例由于来自markupStream()的未捕获异常而崩溃
更新:根据要求,这是日志: https ://pastebin.com/A4vL8zcc
解决方案
由于您使用renderToNodeStream
的是 ,因此在尝试从流中读取某些内容之前,不会完成实际渲染,从日志中的堆栈跟踪可以明显看出:
TypeError: Cannot read property 'length' of undefined
at NotFoundPage.render (~/server/dist/loader.js:43889:23)
at processChild (~/node_modules/react-dom/cjs/react-dom-server.node.development.js:2207:18)
at resolve (~/node_modules/react-dom/cjs/react-dom-server.node.development.js:2064:5)
at ReactDOMServerRenderer.render (~/node_modules/react-dom/cjs/react-dom-server.node.development.js:2349:22)
at ReactDOMServerRenderer.read (~/node_modules/react-dom/cjs/react-dom-server.node.development.js:2323:19)
at ReactMarkupReadableStream._read (~/node_modules/react-dom/cjs/react-dom-server.node.development.js:2735:38)
at ReactMarkupReadableStream.Readable.read (_stream_readable.js:449:10)
at flow (_stream_readable.js:853:34)
=> at resume_ (_stream_readable.js:835:3)
at process._tickCallback (internal/process/next_tick.js:114:19)
这意味着任何错误只发生在流的读取/管道传输期间,即在您的 HTTP 框架中,这对于您的 try/catch 来说太迟了,无法看到它们。
您可能希望使用renderToString
或检测您返回的流以进行错误处理。
推荐阅读
- javascript - 使用 Javascript Canvas 将图像添加到对象
- python-3.x - 在背景图像上的特定坐标处将图像覆盖到背景图像?Python
- php - PHP Mailscript - 添加一个简单的条件来阻止垃圾邮件机器人
- python-3.x - Postgres 函数 - 从 Python 运行,不插入记录
- database - 了解每个范式是否重要
- java - SPRING - CORS中ORIGIN是什么意思
- swift - EAGLContext 到 UIImage
- laravel - SQLSTATE [42S22]:找不到列:1054 未知列(Laravel)
- python - 用其他列填充 NaN 和空值
- android - 如何避免画布的多条路径?