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

rejectOnNotFound throws Error when non-required relation is null #169

Closed
rtnolan opened this issue Aug 25, 2021 · 11 comments
Closed

rejectOnNotFound throws Error when non-required relation is null #169

rtnolan opened this issue Aug 25, 2021 · 11 comments
Labels
out of scope Does not fit into scope

Comments

@rtnolan
Copy link

rtnolan commented Aug 25, 2021

Describe the Bug
I'm attempting to throw an Error when findUnique() doesn't return a value for a given model. However when a relation on that model is null (it's not required) I'm getting an error back in Errors. My Prisma schema looks like:

model User {
  id     String @id @default(cuid())
  email  String @unique
  infoId String? @unique
  Info   Info?  @relation(fields: [infoId], references: [id])
}

model Info {
  id   String @id @default(cuid())
  User User?
}

Prisma Client:

const prisma = new PrismaClient({
  rejectOnNotFound: {
    findUnique: {
      User: (err) => new Error("Could not find user."),
    },
  },
});

To Reproduce
I have a sample repo here: https://github.com/tnolan8/urql-prisma which has a Readme attached.

Expected Behavior
I would not expect there to be any Errors when a non-required relation is null when the Prisma Client is configured to only throw an Error when it's parent is null.

Logs

{
  "errors": [
    {
      "message": "Could not find user.",
      "locations": [{ "line": 12, "column": 5 }],
      "path": ["getUser", "Info"],
      "extensions": {
        "code": "INTERNAL_SERVER_ERROR",
        "exception": {
          "clientVersion": "2.29.0",
          "stacktrace": [
            "Error: Could not find user.",
            "..."
          ]
        }
      }
    }
  ],
  "data": {
    "getUser": {
      "id": "ckfqy3w2q022813mawgzib8x4",
      "email": "test123@gmail.com",
      "Info": null,
      "__typename": "User"
    }
  }
}

Here you can see that it returns the User correctly but also returns an Error.

Environment (please complete the following information):

  • OS: MacOS Big Sur 11.5.1
  • Node 14.15.1
  • typegraphql-prisma version 0.14.8
  • Prisma version 2.29.0
  • TypeScript version 4.3.5
@MichalLytek
Copy link
Owner

Please raise that issue on the Prisma side.

typegraphql-prisma, uses .findUnique() without rejectOnNotFound: true argument, so I can do nothing about it.

@MichalLytek MichalLytek added the out of scope Does not fit into scope label Aug 25, 2021
@rtnolan
Copy link
Author

rtnolan commented Aug 25, 2021

So I originally started a discussion on the Prisma repo, but the actual .findUnique() works fine when I'm not using it with TypeGraphQL. In the example repo above I set up a simple server without TypeGraphQL and it works fine, it's just when I use the default resolvers generated by TypeGraphQL that the problem arises.

@rtnolan
Copy link
Author

rtnolan commented Aug 25, 2021

Sorry I miss-read, your comment. So the issue is on the Prisma side? Could you help me understand a little more what the actual problem is so I can open an issue with Prisma.

@MichalLytek
Copy link
Owner

MichalLytek commented Aug 25, 2021

You are resolving relations by using include in findUnique, which is a wrong approach in GraphQL ecosystem:

const user = await ctx.prisma.user.findUnique({
  where: { id: args.where.id },
  include: { Info: true },
});

typegraphql-prisma has dedicated type field resolvers which are resolving the relations by doing this:

return prisma.user.findUnique({
  where: { id: parent.id },
}).posts();

So looks like your global rejectOnNotFound setting is forcing all .findUnique() calls to throw error, instead of only swapping the thrown errors.

@rtnolan
Copy link
Author

rtnolan commented Aug 25, 2021

Okay I understand now. So the Field Resolver that resolves the relation between the User and Info model needs some way of knowing not to throw an Error if it resolves too null. I'll open an issue over on Prisma. Cheers @MichalLytek 👋

@MichalLytek
Copy link
Owner

MichalLytek commented Aug 25, 2021

Try running this one on your Prisma client:

const prisma = new PrismaClient({
  rejectOnNotFound: {
    findUnique: {
      User: (err) => new Error("Could not find user."),
    },
  },
});

// expect to throw error
await prisma.user.findUnique({
  where: { id: "ckqjgja0b0009rxtp2b0avh92" },
  rejectOnNotFound: true,
});

// expect to not throw anything
await prisma.user.findUnique({
  where: { id: "ckqjgja0b0009rxtp2b0avh92" },
  rejectOnNotFound: false,
});

// expect to not throw anything
await prisma.user.findUnique({
  where: { id: "ckqjgja0b0009rxtp2b0avh92" },
});

@rtnolan
Copy link
Author

rtnolan commented Aug 25, 2021

Yeah so, 1 throws an Error, 2 doesn't, 3 does. It seems that if a relation resolves to Null when I call await prisma.user.findUnique({..}) then it throws an Error. Using include gets around it like you said but I'll go back to my discussion on the Prisma repo and see if there's anything else I can do.

@MichalLytek
Copy link
Owner

I could put rejectOnNotFound: false everywhere in the resolvers but I think Prisma should fix that on their side, so that the default behavior is not affected.

@rtnolan
Copy link
Author

rtnolan commented Aug 25, 2021

I'll mention the issue here once I get it created, thanks for the help again. 👍

@rtnolan
Copy link
Author

rtnolan commented Aug 25, 2021

Raised; prisma/prisma#8929

@MichalLytek
Copy link
Owner

Closing for a housekeeping purposes 🔒 The fix from Prisma will propagate to typegraphql-prisma with a dependency bump.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
out of scope Does not fit into scope
Projects
None yet
Development

No branches or pull requests

2 participants