Skip to content

Adapter Method Promise Rejections are Unhandled, causes Unreliable Upstream Promise Resolutions #1832

@willllhallll

Description

@willllhallll

Describe the bug
Promises that reject with errors from within adapter methods are in some cases unhandled, leading to UnhandledPromiseRejectionWarning and potentially leaving pending upstream promises that never resolve.

An example of such an unhandled promise rejection is during the email sign-in flow. In this case, if the adapter method getUserByEmail rejects with an error, then an UnhandledPromiseRejectionWarning is logged to the node console.

In development, upstream promises (such as the one returned by the client signIn method when redirect is false) that rely on the getUserByEmail promise resolving or rejecting are left indefinitely pending.

In production, upstream promises are eventually rejected by virtue of a 500 response from the server as it deals with the unhandled rejection exception.

Steps to reproduce
Either clone repro:
https://github.com/WillTheVideoMan/nextauth-repro-unhandled-promise-rejection-warning

Or:

  1. Configure next-auth in a development environment with an adapter.
  2. To test this case, configure the adapter such that the adapter methods always reject with an error e.g. provide incorrect database credentials.
  3. Make a request to an endpoint which contains an unhandled adapter promise e.g.
    const profile = await getUserByEmail(email) || { email }
  4. Observe an UnhandledPromiseRejectionWarning warning in the node console.
  5. Observe that any upstream promises such as the one making the request are indefinitely pending.
  6. Deploy instance to a production environment.
  7. Observe that the upstream promises are resolved eventually by virtue of a 500 response.

Expected behavior
Expect all promises which may reject to be handled explicitly.

I think the overall intention here should be to avoid unhandled promise rejections entirely. This would ensure errors more consistently cascade in predictable ways, and importantly, would move in line with the upcoming node v15 revisions: nodejs/node#33021

Screenshots or error logs

(node:21664) UnhandledPromiseRejectionWarning: Error: get_user_by_email_error
    at getUserByEmail (webpack-internal:///./auth/fauna-adapter.js:135:31)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
(node:21664) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 14)

Additional context
Whilst ultimately the production environment is the one to worry about, enabling consistent error handling throughout NextAuth would reduce the disparity between development and production. I discovered this issue exactly because of the lack of promise fulfilment in development, and so I had no way to properly test my implementation of error handling. This is a make-or-break for our testing methodology. It should be that we get the same fundamental behavior in development as we do in production, independent of any intrinsic NextJS magic.

Feedback

  • Found the documentation helpful
  • Found documentation but was incomplete
  • Could not find relevant documentation
  • Found the example project helpful
  • Did not find the example project helpful

Metadata

Metadata

Assignees

No one assigned

    Labels

    adaptersChanges related to the core code concerning database adaptersbugSomething isn't workingenhancementNew feature or requesthelp-neededThe maintainer needs help due to time constraint/missing knowledge

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions