prisma: Prisma crashes with GraphQL queries of nested one-to-many relationship

Bug description

Hi there

We are experiencing a crash when triggering a GraphQL nested query with many-to-many database tables. We have demonstrated the crash only is triggered when:

  • It’s a nested query, and
  • It’s a one-to-many relationship, and
  • It uses findFirst, findUnique or $transaction.

Note: Using findUnique doesn’t crash the app, but this can’t be used because it a one-to-many relationship.

The app is built with Nest.js and uses Apollo GraphQL driver. The app also uses Postgres, and it crashes silently. The only reason we know it crashes because of a log from Postgres: LOG: could not receive data from client: Connection reset by peer

We have tried to export DEBUG="*" to watch out for help logs. However, the last log before the app crashes is: prisma:client:libraryEngine sending request, this.libraryStarted: true

This bug report contains a standalone repository with reproducing steps documented in README.md file. The repo can be found here.

How to reproduce

  1. Clone the standalone reproduction repo (it uses Docker for the app and the database).
  2. yarn install
  3. Run docker compose up, and wait for the app to run by observing the logs.
  4. Now you need to run the migration file within the container, that will also seed the database with data. Run docker exec -it main /bin/sh to get a container shell.
  5. Run the migration file: npx prisma migrate dev.

The app is now running on http:localhost:8080 with data in the database. We need to query these data to trigger the bug.

  1. Open http:localhost:8080/graphql and run the following query:
query {
  cat(id: 1) {
    name
    age
    legs {
      color
      claws {
        length
      }
    }
  }
}

The query has a one-to-many relationship in the legs and claws part.

Now to confirm this only happens when the query uses any of the previously mentioned methods, open src/claws/claws.service.ts and try the methods that are commented at the bottom of the file.

Make sure the app was hot reloaded by observing Docker logs, once hot reloaded, trigger the same query again. Works fine!

Expected behavior

The query doesn’t crash Prisma.

Prisma information

generator client {
  provider      = "prisma-client-js"
  binaryTargets = ["native", "linux-musl-arm64-openssl-3.0.x"]
}

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

model Cat {
  id   Int    @id @default(autoincrement())
  name String
  age  Int

  owner   Owner? @relation(fields: [ownerId], references: [id])
  ownerId Int?

  legs Leg[]
}

model Leg {
  id    Int    @id @default(autoincrement())
  color String

  cat   Cat? @relation(fields: [catId], references: [id])
  catId Int?

  claws Claw[]
}

model Claw {
  id     Int    @id @default(autoincrement())
  length String

  leg   Leg? @relation(fields: [legId], references: [id])
  legId Int?
}

model Owner {
  id   Int    @id @default(autoincrement())
  name String

  Cat   Cat[]
  House House[]
}

model House {
  id      Int    @id @default(autoincrement())
  address String

  owner   Owner? @relation(fields: [ownerId], references: [id])
  ownerId Int?
}

Environment & setup

  • OS: macOS, with Docker
  • Database: PostgreSQL
  • Node.js version: v19.9.0

Prisma Version

prisma                  : 4.12.0
@prisma/client          : 4.12.0
Current platform        : linux-musl-arm64-openssl-3.0.x
Query Engine (Node-API) : libquery-engine 659ef412370fa3b41cd7bf6e94587c1dfb7f67e7 (at node_modules/@prisma/engines/libquery_engine-linux-musl-arm64-openssl-3.0.x.so.node)
Migration Engine        : migration-engine-cli 659ef412370fa3b41cd7bf6e94587c1dfb7f67e7 (at node_modules/@prisma/engines/migration-engine-linux-musl-arm64-openssl-3.0.x)
Format Wasm             : @prisma/prisma-fmt-wasm 4.12.0-67.659ef412370fa3b41cd7bf6e94587c1dfb7f67e7
Default Engines Hash    : 659ef412370fa3b41cd7bf6e94587c1dfb7f67e7
Studio                  : 0.483.0

Revisions

Edit 1: The app crashes only when querying a nested one-to-many relations. Edit 2: I have updated the reproduction repo to include a more concrete example. Edit 3: Title update to mention “one-to-many relationship”, and add a description of the relationship in the query.

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 16 (15 by maintainers)

Most upvoted comments

@MEnnabah yep, I can reproduce this issue using your repo, but everything works with 5.3.0-integration-arm-openssl-5-2-0.1:

image

Can you confirm it on your side as well?

(fyi: you’re using the deprecated beforeExit event which was removed in Prisma 5, and I just removed the whole custom enableShutdownHooks method from your PrismaService to fix the TS error as it was just dead code that did nothing as it has no special meaning for NestJS and you didn’t call it yourself in the application root, however if you were to actually enable the shutdown hooks in NestJS, there’s no need for any special integration with Prisma, you can just use built-in app.enableShutdownHooks())

Unfortunately, using node:18 did not solve the issue in my case.

I’m actually not sure why it works for us. janpio mentioned that it shouldn’t be the case, but for some reason it worked for us, and because we were trying to reduce our image size, when we tried node:20-alpine3.17 it worked too.

While it might be unrelated, our binary targets are defined as the following if you want to try it with that node:20-alpine3.17

binaryTargets   = ["native", "linux-musl-openssl-3.0.x", "debian-openssl-1.1.x", "linux-musl-arm64-openssl-3.0.x", "linux-arm64-openssl-3.0.x"]

Thanks Jan for taking a look into this issue.

As you know Prisma itself does not support GraphQL.

The way we use Prisma is when we receive a GraphQL query, each path of the query gets executed against our database using Prisma.

I totally understand Prisma is a generic ORM, and we don’t expect Prisma to support GraphQL natively.

Look inefficient, but in no way broken.

Would this be an issue, running multiple inefficient requests asynchronously in the same connection, at the same time?

If you look at the reproduction repo, specifically this file (src/claws/claws.service.ts), it’s very weird that Prisma crashes if we use findMany, findFirst, or $transaction. But if we used findUnique it works just fine, even though findUnique was triggered by a GraphQL query!

Can you reproduce the issue with just the Prisma Client queries that your GraphQL library generates and executes?

I guess this can be done by simply translating the queries listed in #18787 (comment) into a Prisma Client API and executing them all at once. Some of these would run in parallel, but others would have to wait for dependencies. Is that right? If yes, I’ll give it a shot.

But I’m hoping someone from Prisma team could run the reproduction repo and comment/uncomment the methods in src/claws/claws.service.ts to get a feeling of the issue. The project is in Docker, no external dependencies needed 😃