Cannot catch unhandled promise rejections
ffxsam opened this issue · 8 comments
This is my endpoint code (using Serverless Framework):
import serverless from 'serverless-http';
import app from './app'; // express app
import withSentry from 'serverless-sentry-lib';
export const handler = withSentry(serverless(app));
I figured this would work since this plugin is meant for serverless, but unfortunately it doesn't handle unexpected/uncaught errors. Is there something else I need to do?
Thanks for the report. I haven't used serverless-http
myself. Possibly another component overwrites the unhandled rejection handler. Do you have a minimal example that reproduces the issue?
@arabold Hey, sorry for the delay! Been a bit busy.
Here's a reproduction: https://github.com/ffxsam/repro-err-handling
When I deploy this to AWS and curl
the API endpoint, I get this response:
{"message": "Internal server error"}
But there are no error reports in Sentry.
(don't forget to change the DSN in serverless.yml
)
Thanks for reporting and providing an example. Indeed I'm able to reproduce this issue now and will release a fix shortly.
Promises can get tricky when they're several levels deep. I'm very curious to see the solution to this problem.
I have published v2.3.0 of the serverless-sentry-lib
. An update to the plugin is not necessary, just the lib. This should fix the reporting of both unhandled rejections and uncaught exceptions.
The lib handles two cases now (based on your serverless-http
example):
// Throw an unhandled rejection
router.get("/test1", (req, res) => {
new Promise((resolve, reject) => {
reject("Reject this!");
});
res.json({ success: true });
});
// Throw an uncaught exception
router.get("/test2", function (req, res, next) {
setImmediate(() => {
throw new Error("Catch this!");
});
res.json({ success: true });
});
There's a third case that is handled by Express automatically. You can register a custom error handling middleware that forwards errors to Sentry in this case as well:
router.get("/test2", async (req, res) => {
throw new Error("Catch this!");
res.json({
success: true,
});
});
router.use(function (err, req, res, next) {
Sentry.captureException(err);
res.json({ message: error.message });
});
Hope this solves all issues for you. Please let me know if you encounter anything else!
Amazing, thank you!