express-async-errors
express-async-errors copied to clipboard
Lint error with TypeScript
Using the async handler with this lib leads to the following lint error as the return type of async handler is a Promise<> and the expected one is just a void.
Error Message:
Promise returned in function argument where a void return was expected. (@typescript-eslint/no-misused-promises)
I am not sure if the type definition of the express handler can be changed in this lib's definitions. Create a ticket just in case if it's possible.
Me too getting the same error. So I tried doing something like this:
export const tempName = (req: Request, res: Response, next: NextFunction) => async () => { // everything else with await }
And then the linting error is gone.
Any updates here?
Any updates here?
Can you share some code where you are getting this lint error? I think I know the solution
Error message
ESLint: Promise returned in function argument where a void return was expected.(@typescript-eslint/no-misused-promises)
Code:
import express, { Request, Response } from 'express';
import 'express-async-errors';
async function asyncThrowError(): Promise<void> {
await Promise.all([]);
throw new Error('Test error');
}
async function main(): Promise<void> {
// TODO: remove later
await Promise.all([]);
const app = express();
app.get('/async-error', async (_request: Request, response: Response) => {
await asyncThrowError();
response.status(200).json({ success: true });
});
app.listen(40512);
}
main()
.then(() => {
// eslint-disable-next-line no-console
console.log('Application started');
})
.catch((error: Error) => {
// eslint-disable-next-line no-console
console.error('Application startup error', { error });
});
app.get('/async-error', async (_request: Request, response: Response): Promise<void> // Added this => {
await asyncThrowError();
response.status(200).json({ success: true });
});
or
app.get('/async-error', async (_request: Request, response: Response) => {
await asyncThrowError();
return response.status(200).json({ success: true }); // Added return
});
Let me know if one of them works.
Thank you for your suggestions!
Unfortunately, both versions give me the same issue as before.
Same error . Plus , it does not tend to handle the async errors resulting from using Multer for file uploads
~I have the solution!~
EDIT: Unfortunately, fixing the RequestHandler type is only part of the solution:
- we cannot fix the
ErrorRequestHandlertype because it's declared astype, not asinterface. I assume, we can discuss this change with the maintainer of the types package - the express application
Applicationtype and the routerIRoutertype are also affected by the fix, as they are extended from theRequestHandlertype. So they will trigger the sameeslinterror when using them e.g. as an argument forhttps.createServer
At the moment, this is above the time budget I have for the task. Maybe someone else would like to pick it up from here
The partial solution
- It will not remove the eslint error from error-handling routes
- It may introduce a few new instances of this eslint error. Yet, probably much less than will eliminate
Create or extend an existing .d.ts file in your project with the following code (e.g. types-override.d.ts):
import type { Request, Response } from 'express';
import type { ParamsDictionary, Query } from 'express-serve-static-core';
import type { NextFunction } from 'express-serve-static-core';
declare module 'express-serve-static-core' {
export interface RequestHandler<
P = ParamsDictionary,
ResBody = any,
ReqBody = any,
ReqQuery = Query,
LocalsObj extends Record<string, any> = Record<string, any>
> {
(
req: Request<P, ResBody, ReqBody, ReqQuery, LocalsObj>,
res: Response<ResBody, LocalsObj>,
next: NextFunction
): void | Promise<void>;
}
}
- In case you are creating a new file and your
tsconfig.jsonhas the"include"section then ensure that the file is covered by the patterns of the section - For the TypeScript versions older than 3.8 you can replace
import typewith justimport
You are done!
The type is fixed, so you will see no @typescript-eslint/no-misused-promises) error for your routes
Comments on the implementation
The conflict we are having here is with the type RequestHandler of express, which is extended from the type RequestHandler of the express-serve-static-core - its return type is void, and we are providing a function with the return type Promise<void>. If we patch the RequestHandler of the express it would become incompatible with the root type, this is why we are extending directly the root type
The feature we are using here is called merging interfaces it allows extending existing interfaces by re-declaring them
So, here we duplicate the definition of the RequestHandler type from the express-serve-static-core but change the return type from void to void | Promise<void>