Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Accept async middlewares #17421

Open
4 tasks done
benmccann opened this issue Jun 8, 2024 · 5 comments
Open
4 tasks done

Accept async middlewares #17421

benmccann opened this issue Jun 8, 2024 · 5 comments

Comments

@benmccann
Copy link
Collaborator

benmccann commented Jun 8, 2024

Description

Most Vite middlewares need to be async especially because many of Vite's own APIs that you would be calling like ssrLoadModule are async. However, middlewares.use does not accept async methods. This makes for a pretty awkward dance to handle promise rejections and worse means that many users will overlook error handling altogether resulting in server crashes

Also, it would make sense for Vite's errorMiddleware to be called in the .catch when invoking the promise as the rejection handler, but that's impossible for users to do as it's not exported. However, this could be done internally in Vite.

Suggested solution

Override middlewares.use to accept async implementations or add a middlewares.useAsync method

Alternative

  • have every consumer add a workaround for it instead of adding it directly in Vite. also expose the errorMiddleware or have every consumer wrap their implementation in a try/catch so that it can never throw and implement their own custom error handling
  • switch away from connect to another server implementation which has native async handling like koa

Additional context

No response

Validations

@benmccann benmccann changed the title Add a middlewares.useAsync method Accept async middlewares Jun 8, 2024
@bluwy
Copy link
Member

bluwy commented Jun 10, 2024

Perhaps we could patch connect so that it handles .catch()?

IIUC here and here could have a trailing .catch(err => {}) which would call next(err), and it should properly work again. Not sure if they still accept changes upstream though given the time.

@benmccann
Copy link
Collaborator Author

Yeah, sadly there's been no commits to connect for three years, so I don't feel very optimistic we could get a change in.

@benmccann
Copy link
Collaborator Author

Express 5 has added support for this:

Request middleware and handlers that return rejected promises are now handled by forwarding the rejected value as an Error to the error handling middleware. This means that using async functions as middleware and handlers are easier than ever. When an error is thrown in an async function or a rejected promise is awaited inside an async function, those errors will be passed to the error handler as if calling next(err).

@benmccann
Copy link
Collaborator Author

I just tested and polka has support for it as well. If there's an unhandled error in an async handler then options.onError will be called. You can also see that its middleware returns a Promisable in its types.

Perhaps we should switch to polka 1.0.0-next.25 as SvelteKit has done since polka is both better maintained and supports async middleware.

@benmccann
Copy link
Collaborator Author

Ah, there's a PR to switch to polka. So this would be addressed by #17569

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants