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

findFirstOrThrow / findUniqueOrThrow errors are not reported via error event #14933

Closed
Tracked by #16162
Dam-Buty opened this issue Aug 22, 2022 · 6 comments · Fixed by prisma/prisma-engines#3356
Closed
Tracked by #16162
Assignees
Labels
bug/1-unconfirmed Bug should have enough information for reproduction, but confirmation has not happened yet. kind/bug A reported bug. team/client Issue for team Client. topic: rejectOnNotFound / *OrThrow topic: throws
Milestone

Comments

@Dam-Buty
Copy link

Bug description

When findFirstOrThrow or findUniqueOrThrow can't find a model instance, an error is thrown. This error is not currently catchable as it doesn't trigger a Prisma error event, nor is it thrown by next inside of middlewares.

This is the issue which was described by @bbenezech in this comment and confirmed to be a bug by @janpio .

For us the immediate effect is that the error is not logged by our custom logger, which results in 5 or 6 error lines in Datadog (triggering error alerting).

How to reproduce

  1. Setup a prisma.$on("error", ...) event hook
  2. Setup a prisma.$use(...) middleware
  3. Use the Prisma client to make a findFirstOrThrow query that is guaranteed to fail
  4. The error is thrown and logged directly in console without going through the error event hook, or being thrown inside the middleware

Expected behavior

I would expect one of those two behaviours (or both) :

  • The error event hook is called
  • The error is thrown by next in the middleware so i can catch it and treat it accordingly

Prisma information

This happens for all models but should be reproducible with this minimal schema :

datasource db {
  provider = "postgresql"
  url      = env("DB_URL")
}

generator client {
  provider        = "prisma-client-js"
  previewFeatures = ["interactiveTransactions", "orderByNulls"]
}

model User {
  id                 Int                       @id @default(autoincrement())
  email              String                    @unique
}

Client queries :

  const prisma = new PrismaClient({
    datasources: {
      db: {
        url: config.database.url,
      },
    },
    log: [
      { level: "query", emit: "event" },
      { level: "info", emit: "event" },
      { level: "warn", emit: "event" },
      { level: "error", emit: "event" },
    ],
  });


  prisma.$on("info", (event) => {
    log.info(`[prisma] ${event.message}`, {
      target: event.target,
    });
  });

  prisma.$on("warn", (event) => {
    log.warn(`[prisma] ${event.message}`, {
      target: event.target,
    });
  });

  prisma.$on("error", (event) => {
    // This code does not appear to be called when throwing
    log.error(`[prisma] ${event.message}`, {
      target: event.target,
    });
  });

  prisma.$use(async (params, next) => {
    console.log(1, params);
    // here, `params.action` is marked as `findUnique` so we can't determine that an `...OrThrow` variant has been used
    const res = await next(params);
    console.log(2, res);
    // here, `res` is `null`. This line is displayed in console before the error message
    return res;
  });

  // There is no user with ID 0 in db
  const test = await prisma.user.findUniqueOrThrow({ where: { id: 0 } });

  console.log(3, test);

☝️ The above code returns the following in console :

1 {
  args: { where: { id: 0 } },
  dataPath: [],
  runInTransaction: false,
  action: 'findUnique',
  model: 'User'
}
2 null
NotFoundError: No User found

Environment & setup

The code runs on this Docker image : node:16-alpine

  • OS: Alpine Linux
  • Database: PostgreSQL
  • Node.js version: 16.17.0

Prisma Version

prisma                  : 4.2.0
@prisma/client          : 4.2.0
Current platform        : linux-musl
Query Engine (Node-API) : libquery-engine 2920a97877e12e055c1333079b8d19cee7f33826 (at node_modules/@prisma/engines/libquery_engine-linux-musl.so.node)
Migration Engine        : migration-engine-cli 2920a97877e12e055c1333079b8d19cee7f33826 (at node_modules/@prisma/engines/migration-engine-linux-musl)
Introspection Engine    : introspection-core 2920a97877e12e055c1333079b8d19cee7f33826 (at node_modules/@prisma/engines/introspection-engine-linux-musl)
Format Binary           : prisma-fmt 2920a97877e12e055c1333079b8d19cee7f33826 (at node_modules/@prisma/engines/prisma-fmt-linux-musl)
Default Engines Hash    : 2920a97877e12e055c1333079b8d19cee7f33826
Studio                  : 0.469.0
Preview Features        : interactiveTransactions, orderByNulls
@Dam-Buty Dam-Buty added the kind/bug A reported bug. label Aug 22, 2022
@danstarns danstarns added team/client Issue for team Client. bug/1-unconfirmed Bug should have enough information for reproduction, but confirmation has not happened yet. labels Aug 24, 2022
@SevInf SevInf self-assigned this Sep 20, 2022
@SevInf SevInf changed the title findFirstOrThrow / findUniqueOrThrow errors are not catchable findFirstOrThrow / findUniqueOrThrow errors are not reported via error event Sep 20, 2022
@SevInf SevInf removed their assignment Sep 23, 2022
@miguelff miguelff added this to the 4.6.0 milestone Nov 2, 2022
@miguelff miguelff modified the milestones: 4.6.0, 4.7.0 Nov 8, 2022
@miguelff
Copy link
Contributor

miguelff commented Nov 8, 2022

Reopening until client changes to use the server endpoints have landed xref: #16162

@miguelff
Copy link
Contributor

Superseded by #16226

@SpecialAro
Copy link

Hello!

Sorry for writing on a closed issue but, after updating @prisma/client from 4.6.1 to 4.7.0 I'm having an issue with findUniqueOrThrow methods. I'm writing on this issue because I think that the PR that was merged to fix this was actually what "broke" it for me.

For instance, for this code:

  try {
    const secret = await prisma.jwtSecrets.findUniqueOrThrow({
      where: { userId: userId },
    });

    if (secret.jwtSecret === null) {
      throw new Error();
    } else {
      return { jwtSecret: secret.jwtSecret };
    }
  } catch {
    return { message: 'Something went wrong!' };
  }

it is throwing me some errors on the console like so:

prisma:error
Invalid `prisma.jwtSecrets.findUniqueOrThrow()` invocation:


Failed to validate the query: `Field does not exist on enclosing type.` at `Query.findManyJwtSecretsOrThrow`

A way to get around that is to ditch the OrThrow method and use findUnique and throw and error manually if there is no secret:

const secret = await prisma.jwtSecrets.findUnique({
      where: { userId: userId },
    });

    if (!secret || secret.jwtSecret === null) {
      throw new Error();
    } else {
      return { jwtSecret: secret.jwtSecret };
    }

Though, this approach is undesirable because I'm not using a prisma functionality that is quite useful.

Am I doing something wrong? Can anybody help me?

Thank you in advance, and I apologize if I lack the knowledge to proper do something, my basis is from Electric Engineering and not IT.

@miguelff
Copy link
Contributor

Hello @SpecialAro!

Though, this approach is undesirable because I'm not using a prisma functionality that is quite useful.

In this case you are not only checking the existence of a jwtSecret, for which you might use the findXOrThrow method, but also checking that in case it exists, its jwtSecret property has a not null value.

For that, I think the appropriate API is the one you suggest, to use findUnique and check manually. It's more compact, and easier to understand code in my opinion.

Having said that, the error logged in the console informs about a field not present in the model, which should be a bug. Would you mind filing a new bug report, please? and include information for reproduction, including a schema file, so we can help you better?

Thank you.

@miguelff
Copy link
Contributor

@SpecialAro no need to report anymore. Your report was also captured by #16549. A fix is on the way. prisma/prisma-engines#3458

@SpecialAro
Copy link

@SpecialAro no need to report anymore. Your report was also captured by #16549. A fix is on the way. prisma/prisma-engines#3458

Thank you so much @miguelff ! Got caught up with work and didn't had time to open an issue sooner, sorry.

Nevertheless, I'm really glad that a fix is already on the way 😁 I'll hold back the update until further notice, then.

Thank you again, loving prisma so far ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug/1-unconfirmed Bug should have enough information for reproduction, but confirmation has not happened yet. kind/bug A reported bug. team/client Issue for team Client. topic: rejectOnNotFound / *OrThrow topic: throws
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants