[英]Properly catching a async function node.js
My attempt was: 我的尝试是:
my server.js has the following: 我的server.js具有以下内容:
const app = express();
app.get('/*', loader(filePath, observer));
The file i'm trying to call sometimes loads with errors, which bubbles up to be uncaughtExceptions which restarts the server. 我尝试调用的文件有时会加载错误,并冒泡为uncaughtExceptions,从而重新启动服务器。 I need to catch it in the catch{} somehow
我需要以某种方式抓住它{}
export default (htmlFilePath, observer) => async (req, res) => {
try {
.......
.......
.......
const markupStream = renderToNodeStream(
<Provider store={store}>
<ConnectedRouter history={history} location={context}>
<App/>
</ConnectedRouter>
</Provider>
);
if (context.url) {
return res.redirect(301, context.url)
}
return fs.createReadStream(htmlFilePath)
.pipe(htmlReplace('#root', markupStream))
.pipe(replaceStream('__SERVER_DATA__', serialize(store.getState())))
.pipe(res);
} 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);
}
}
What's the right way to do this? 什么是正确的方法? My issue before doing
().catch(err
was that I always got uncaughtException
, it did not ever go into the catch in the try{}
catch{}
within the function 在执行
().catch(err
之前,我的问题是我总是遇到uncaughtException
,它从未在函数中的try{}
catch{}
陷入().catch(err
When using an async
express middleware, in order to catch any rejections and pass that rejection to the express error handler, you need a wrapper: 使用
async
快速中间件时,为了捕获任何拒绝并将该拒绝传递给快速错误处理程序,您需要一个包装器:
async-handler.js 异步handler.js
const asyncHandler = fn => (req, res, next) => {
return Promise
.resolve(fn(req, res, next))
.catch(next);
};
module.exports = asyncHandler;
ssr-stream.js SSR-stream.js
const ssrStream = (htmlFilePath, observer) => async (req, res) => {
// If you wrap this middleware with asyncHandler
// No need try/catch, you can let it bubble up, and it will go to express error middleware
// Of course you can do it, and handle the custom error here, and let it bubble up for generic errors.
}
export default ssrStream;
index.js index.js
const app = express();
const asyncHandler = require('./async-handler');
const loader = require('./ssr-stream');
// Wrap your async function, with asyncHandler
app.get('/foo', asyncHandler(async(req, res) => {
throw new Error('Foo'); // This will go to the express error middleware
}));
app.get('/*', asyncHandler(loader(filePath, observer)));
app.use((err, req, res, next) => {
// Handle the error type, and set the correct status code
const status = 500;
res
.status(status)
.end(err.message);
});
You should check it in your function expression, not in the function declaration. 您应该在函数表达式中检查它,而不是在函数声明中检查它。 In the function itself, just throw whenever there is an error.
在函数本身中,只要有错误就抛出。 Then, wrap it in a try/catch block :
然后,将其包装在try / catch块中:
try {
await ssrStream(htmlFilePath, observer);
} catch(e) {
// Handle error here
}
It's also possible to chain a catch
directly after your async function (which is essentially a promise) : 也可以在异步函数之后直接链接
catch
(本质上是一个承诺):
await ssrStream(htmlFilePath, observer)
.catch(e => // handle error here);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.