Nexus-plugin-prisma: Engine has already been stopped

Created on 8 Jul 2019  路  11Comments  路  Source: graphql-nexus/nexus-plugin-prisma

Every once in a while, I get the following error message in my graphql-yoga server:

Error: Error in Photon:
Engine has already been stopped
    at PhotonFetcher.<anonymous> (/Users/.../node_modules/@generated/photon/index.js:35:23)
    at Generator.throw (<anonymous>)
    at rejected (/Users/.../node_modules/@generated/photon/index.js:5:65)
    at processTicksAndRejections (internal/process/task_queues.js:86:5)

Restarting the graphql-yoga server solves the problem.

typbug

Most helpful comment

Reproduction of "Engine has already been stopped" Photonjs prisma/prisma2#113

I have been working on Photon's typescript/graphql-auth example, working around errors and generally making the example ready for use as a boilerplate for new projects. I run into this error periodically and have determined how to reliably reproduce it.

Note: This error is triggered by invalid graphql input. With proper server-side input validation, this error should never occur.

Note: The 'official' Photon typescript/graphql-auth example _does not_ demonstrate this error.

My system:

macOS: 10.14.6
prisma2: [email protected], binary version: 4f33077038a490e4b2c1c260f109309e4a447181
node: 12.5.0
yarn: 1.16.0

1. Clone the repo, install dependencies and start the server:

git clone -b engine-stopped https://github.com/gihrig/hello-photon-graphql-auth.git
cd hello-photon-graphql-auth
yarn
yarn dev
Open playground at http://localhost:4000/

2. Execute the signup mutation to confirm the server is working.

mutation {
  signup(
      name: "Thomas"
      email: "[email protected]"
      password: "graphql"
  ) {
    token
  }
}

This should work as expected

3. Execute the signup mutation again, but with a missing email key

mutation {
  signup(
      name: "Angie"
      password: "graphql"
  ) {
    token
  }
}

This throws an error as expected, and apparently, crashes the 'engine'.


Console output

Error: 
Invalid `ctx.photon.users.create()` invocation in /Users/glen/Documents/JavaScript/Research/hello-photon-graphql-auth/src/resolvers/Mutation.ts:19:45

15 resolve: async (parent,[object Object], ,[object Object], name,[object Object], email,[object Object], password ,[object Object],[object Object], ctx) => {
16   // User must not exist
17   // See permissions
18   const hashedPassword = await hash(password, 10)
19   const user = await ctx.photon.users.create({
       data: {
         name: 'Angie',
     +   email: String,
         password: '$2b$10$S141uyWaOXDB0VEBUuC5dO.rsIWkdI9pa0lhKr/95TiXqiBstWQwu',
     ?   id?: ID,
     ?   posts?: {
     ?     create?: PostCreateWithoutAuthorInput,
     ?     connect?: PostWhereUniqueInput
     ?   }
       }
     })

Argument email for data.email is missing.

Note: Lines with + are required, lines with ? are optional.

    at Document.validate (/Users/glen/Documents/JavaScript/Research/hello-photon-graphql-auth/node_modules/@generated/photon/runtime/index.js:1476:23)
    at UserClient.get document [as document] (/Users/glen/Documents/JavaScript/Research/hello-photon-graphql-auth/node_modules/@generated/photon/index.js:268:22)
    at UserClient.then (/Users/glen/Documents/JavaScript/Research/hello-photon-graphql-auth/node_modules/@generated/photon/index.js:290:61)

4. Correct the mutation and run again

mutation {
  signup(
      name: "Angie"
      email: "[email protected]"
      password: "graphql"
  ) {
    token
  }
}

Even though the mutation is now correct, an error is thrown suggesting the server has shut down.

Error: Error in Photon: 
{
  "name": "RequestError",
  "code": "ECONNREFUSED",
  "host": "localhost:55999",
  ...


full error

Error: Error in Photon: 
{
  "name": "RequestError",
  "code": "ECONNREFUSED",
  "host": "localhost:55999",
  "hostname": "localhost",
  "method": "POST",
  "path": "/",
  "protocol": "http:",
  "url": "http://localhost:55999/",
  "gotOptions": {
    "path": "/",
    "protocol": "http:",
    "slashes": true,
    "auth": null,
    "host": "localhost:55999",
    "port": "55999",
    "hostname": "localhost",
    "hash": null,
    "search": null,
    "query": null,
    "pathname": "/",
    "href": "http://localhost:55999/",
    "retry": {
      "methods": {},
      "statusCodes": {},
      "errorCodes": {}
    },
    "headers": {
      "user-agent": "got/9.6.0 (https://github.com/sindresorhus/got)",
      "content-type": "application/json",
      "accept": "application/json",
      "accept-encoding": "gzip, deflate",
      "content-length": 274
    },
    "hooks": {
      "beforeRequest": [],
      "beforeRedirect": [],
      "beforeRetry": [],
      "afterResponse": [],
      "beforeError": [],
      "init": []
    },
    "decompress": true,
    "throwHttpErrors": true,
    "followRedirect": true,
    "stream": false,
    "form": false,
    "json": true,
    "cache": false,
    "useElectronNet": false,
    "body": "{\"query\":\"mutation {\\n  createOneUser(data: {\\n    name: \\\"Angie\\\"\\n    email: \\\"[email protected]\\\"\\n    password: \\\"$2b$10$cG/LyfnNyjWeHyG6B2aSHeOjkXso.hTEaIKsm9kGpXqeGjE2wQ9zK\\\"\\n  }) {\\n    id\\n    email\\n    password\\n    name\\n  }\\n}\",\"variables\":{},\"operationName\":\"\"}",
    "method": "POST",
    "forceRefresh": true
  }
}
    at PhotonFetcher.<anonymous> (/Users/glen/Documents/JavaScript/Research/hello-photon-graphql-auth/node_modules/@generated/photon/index.js:34:23)
    at Generator.throw (<anonymous>)
    at rejected (/Users/glen/Documents/JavaScript/Research/hello-photon-graphql-auth/node_modules/@generated/photon/index.js:5:65)
    at processTicksAndRejections (internal/process/task_queues.js:82:5)

5. Run the correct mutation one more time to produce "Engine has already been stopped".

mutation {
  signup(
      name: "Angie"
      email: "[email protected]"
      password: "graphql"
  ) {
    token
  }
}
Error: Error in Photon: 
Engine has already been stopped
    at PhotonFetcher.<anonymous> (/Users/glen/Documents/JavaScript/Research/hello-photon-graphql-auth/node_modules/@generated/photon/index.js:34:23)
    at Generator.throw (<anonymous>)
    at rejected (/Users/glen/Documents/JavaScript/Research/hello-photon-graphql-auth/node_modules/@generated/photon/index.js:5:65)

All 11 comments

Can you provide us with a minimal reproduction? The provided information isn't sufficient for triaging this issue.

This has stopped. I will report back if it occurs again, and will then try to reproduce.

@iherger are you using any watch command to reload your yoga server?

@timsuchanek , yes, I am using
```
"dev": "ts-node-dev -r dotenv/config --no-notify --respawn --transpileOnly ./src",
````

Using now dev and now - happening both locally and on now.sh - not using graphql-yoga so most likely not an issue to do with that specifically - regenerating the photon client seems to work for me, but inconsistently

I am working on photonjs graphql-auth TS example. I'm running the server with ts-node-dev

"dev": "ts-node-dev --no-notify --respawn --transpileOnly ./src",

For me, the error only happens after another error, typically caused by findOne encountering no result and throwing

Error: Error in Photon: 
ConnectorError(RecordDoesNotExist)
    at Object.<anonymous> (/Users/glen/Documents/JavaScript/Research/hello-photon-graphql-auth/src/resolvers/Mutation.ts:56:17)
    at step (/Users/glen/Documents/JavaScript/Research/hello-photon-graphql-auth/src/resolvers/Mutation.ts:32:23)
    at Object.throw (/Users/glen/Documents/JavaScript/Research/hello-photon-graphql-auth/src/resolvers/Mutation.ts:13:53)
    at rejected (/Users/glen/Documents/JavaScript/Research/hello-photon-graphql-auth/src/resolvers/Mutation.ts:5:65)
    at processTicksAndRejections (internal/process/task_queues.js:82:5)

As mentioned in the OP, this error is intermittent. I can execute the code that throws RecordDoesNotExist 25 times and Engine has already been stopped does not occur. When it does occur, it's typically no more that 3 - 5 other errors into the server session. I am not able to reproduce Engine has already been stopped on demand.

Reproduction of "Engine has already been stopped" Photonjs prisma/prisma2#113

I have been working on Photon's typescript/graphql-auth example, working around errors and generally making the example ready for use as a boilerplate for new projects. I run into this error periodically and have determined how to reliably reproduce it.

Note: This error is triggered by invalid graphql input. With proper server-side input validation, this error should never occur.

Note: The 'official' Photon typescript/graphql-auth example _does not_ demonstrate this error.

My system:

macOS: 10.14.6
prisma2: [email protected], binary version: 4f33077038a490e4b2c1c260f109309e4a447181
node: 12.5.0
yarn: 1.16.0

1. Clone the repo, install dependencies and start the server:

git clone -b engine-stopped https://github.com/gihrig/hello-photon-graphql-auth.git
cd hello-photon-graphql-auth
yarn
yarn dev
Open playground at http://localhost:4000/

2. Execute the signup mutation to confirm the server is working.

mutation {
  signup(
      name: "Thomas"
      email: "[email protected]"
      password: "graphql"
  ) {
    token
  }
}

This should work as expected

3. Execute the signup mutation again, but with a missing email key

mutation {
  signup(
      name: "Angie"
      password: "graphql"
  ) {
    token
  }
}

This throws an error as expected, and apparently, crashes the 'engine'.


Console output

Error: 
Invalid `ctx.photon.users.create()` invocation in /Users/glen/Documents/JavaScript/Research/hello-photon-graphql-auth/src/resolvers/Mutation.ts:19:45

15 resolve: async (parent,[object Object], ,[object Object], name,[object Object], email,[object Object], password ,[object Object],[object Object], ctx) => {
16   // User must not exist
17   // See permissions
18   const hashedPassword = await hash(password, 10)
19   const user = await ctx.photon.users.create({
       data: {
         name: 'Angie',
     +   email: String,
         password: '$2b$10$S141uyWaOXDB0VEBUuC5dO.rsIWkdI9pa0lhKr/95TiXqiBstWQwu',
     ?   id?: ID,
     ?   posts?: {
     ?     create?: PostCreateWithoutAuthorInput,
     ?     connect?: PostWhereUniqueInput
     ?   }
       }
     })

Argument email for data.email is missing.

Note: Lines with + are required, lines with ? are optional.

    at Document.validate (/Users/glen/Documents/JavaScript/Research/hello-photon-graphql-auth/node_modules/@generated/photon/runtime/index.js:1476:23)
    at UserClient.get document [as document] (/Users/glen/Documents/JavaScript/Research/hello-photon-graphql-auth/node_modules/@generated/photon/index.js:268:22)
    at UserClient.then (/Users/glen/Documents/JavaScript/Research/hello-photon-graphql-auth/node_modules/@generated/photon/index.js:290:61)

4. Correct the mutation and run again

mutation {
  signup(
      name: "Angie"
      email: "[email protected]"
      password: "graphql"
  ) {
    token
  }
}

Even though the mutation is now correct, an error is thrown suggesting the server has shut down.

Error: Error in Photon: 
{
  "name": "RequestError",
  "code": "ECONNREFUSED",
  "host": "localhost:55999",
  ...


full error

Error: Error in Photon: 
{
  "name": "RequestError",
  "code": "ECONNREFUSED",
  "host": "localhost:55999",
  "hostname": "localhost",
  "method": "POST",
  "path": "/",
  "protocol": "http:",
  "url": "http://localhost:55999/",
  "gotOptions": {
    "path": "/",
    "protocol": "http:",
    "slashes": true,
    "auth": null,
    "host": "localhost:55999",
    "port": "55999",
    "hostname": "localhost",
    "hash": null,
    "search": null,
    "query": null,
    "pathname": "/",
    "href": "http://localhost:55999/",
    "retry": {
      "methods": {},
      "statusCodes": {},
      "errorCodes": {}
    },
    "headers": {
      "user-agent": "got/9.6.0 (https://github.com/sindresorhus/got)",
      "content-type": "application/json",
      "accept": "application/json",
      "accept-encoding": "gzip, deflate",
      "content-length": 274
    },
    "hooks": {
      "beforeRequest": [],
      "beforeRedirect": [],
      "beforeRetry": [],
      "afterResponse": [],
      "beforeError": [],
      "init": []
    },
    "decompress": true,
    "throwHttpErrors": true,
    "followRedirect": true,
    "stream": false,
    "form": false,
    "json": true,
    "cache": false,
    "useElectronNet": false,
    "body": "{\"query\":\"mutation {\\n  createOneUser(data: {\\n    name: \\\"Angie\\\"\\n    email: \\\"[email protected]\\\"\\n    password: \\\"$2b$10$cG/LyfnNyjWeHyG6B2aSHeOjkXso.hTEaIKsm9kGpXqeGjE2wQ9zK\\\"\\n  }) {\\n    id\\n    email\\n    password\\n    name\\n  }\\n}\",\"variables\":{},\"operationName\":\"\"}",
    "method": "POST",
    "forceRefresh": true
  }
}
    at PhotonFetcher.<anonymous> (/Users/glen/Documents/JavaScript/Research/hello-photon-graphql-auth/node_modules/@generated/photon/index.js:34:23)
    at Generator.throw (<anonymous>)
    at rejected (/Users/glen/Documents/JavaScript/Research/hello-photon-graphql-auth/node_modules/@generated/photon/index.js:5:65)
    at processTicksAndRejections (internal/process/task_queues.js:82:5)

5. Run the correct mutation one more time to produce "Engine has already been stopped".

mutation {
  signup(
      name: "Angie"
      email: "[email protected]"
      password: "graphql"
  ) {
    token
  }
}
Error: Error in Photon: 
Engine has already been stopped
    at PhotonFetcher.<anonymous> (/Users/glen/Documents/JavaScript/Research/hello-photon-graphql-auth/node_modules/@generated/photon/index.js:34:23)
    at Generator.throw (<anonymous>)
    at rejected (/Users/glen/Documents/JavaScript/Research/hello-photon-graphql-auth/node_modules/@generated/photon/index.js:5:65)

I can confirm this. Appears to be a bug in nexus prisma where it is calling .disconnect() when the server throws any error.

Hey everyone 馃憢, I cannot reproduce this issue anymore. I tried @gihrig's reproduction (by removing the yup's validation middlewares), photon does show an error, but sending a valid query again does work properly.

@pantharshit00 There's never been some code that would call .disconnect() when an error is thrown. Maybe something has been fixed on photon's side by then.

I'm closing for now, if someone experiences that issue again, please post a comment and I'll reopen

I can confirm: The error is not reproducible with preview-8.

I did not test with earlier versions.

I was not able to test with preview-10 due to issues with #372, but a new project created with preview-10, prisma2 init and graphql-auth example works as expected when run on the error reproduction routine above.

When I get my dev project working under preview-10, I'll post back with results.

Same error occurred for me when I had included the following to the main index.js file:

// Begin GraphQLServer
server
  .start(options)
  .catch(e => {
    console.error(e)
  })
  .finally(async () => {
    await photon.disconnect()
  })

Once I removed the photon.disconnect(), I stopped getting this error message. Basically, an error throw already disconnects the engine, and there鈥檚 no need to explicitly disconnect it again.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ndom91 picture ndom91  路  4Comments

mateja176 picture mateja176  路  5Comments

macrozone picture macrozone  路  3Comments

aqwert picture aqwert  路  3Comments

marticrespi picture marticrespi  路  4Comments