There are numerous Stack Overflow questions that share a similar title, but it seems none of them address this particular inquiry.
I'm in the process of developing a wrapper for an express RequestHandler
that can catch errors in asynchronous handlers and then call next
with the error.
The concept is to be able to use code like the following:
function tryCatchNext<
P = ParamsDictionary,
ResBody = any,
ReqBody = any,
ReqQuery = ParsedQs,
Locals extends Record<string, any> = Record<string, any>
>(
callback: RequestHandler<P, ResBody, ReqBody, ReqQuery, Locals>
): RequestHandler<P, ResBody, ReqBody, ReqQuery, Locals> {
return async (req, res, next) => {
try {
await callback(req, res, next);
} catch (err) {
next(err);
}
};
}
app.get('/:foo', tryCatchNext(async (req, res, next) => {
// `foo` is not a known parameter, but no error
if (req.params.foo === 'bar') {
throw new Error('That was a bar.');
}
// does not result in an error
// @ts-expect-error
console.log(req.params.bar);
res.send('Not a bar');
}));
When I have just the handler, req
has access to its params
. However, within tryCatchNext()
, req
loses that access. I believe this is due to attempting to infer the return value from the callback provided instead of the generic types in its context.
Everything functions perfectly if I precede it with a dummy handler so that the ...handlers
rest parameter of .get()
is already inferred.
app
.get('/:foo', (req, res, next) => next(), tryCatchNext(async (req, res, next) => {
// ...
}));
Is there a method to work around this issue without explicitly specifying each of the generic type parameters?