My attempt was:
my server.js has the following:
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. 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
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-handler.js
const asyncHandler = fn => (req, res, next) => {
return Promise
.resolve(fn(req, res, next))
.catch(next);
};
module.exports = asyncHandler;
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
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 {
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) :
await ssrStream(htmlFilePath, observer)
.catch(e => // handle error here);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.