From 95ce26fa14269e91c156c6b828169ea6cfcf2ab7 Mon Sep 17 00:00:00 2001 From: Serhii Tatarintsev Date: Tue, 20 Feb 2024 10:18:03 +0100 Subject: [PATCH] feat(client): Mention Accelerate in "Too many connections" errors (#23113) * feat(client): Mention Accelerate in "Too many connections" errors Close prisma/team-orm#945 * initial link * Update packages/client/src/runtime/core/errors/utils/prismaGraphQLToJSError.ts --------- Co-authored-by: Jan Piotrowski --- .../core/engines/binary/BinaryEngine.ts | 6 +++--- .../core/engines/data-proxy/DataProxyEngine.ts | 4 ++-- .../core/engines/library/LibraryEngine.ts | 4 +++- .../errors/utils/prismaGraphQLToJSError.ts | 18 +++++++++++++++++- 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/packages/client/src/runtime/core/engines/binary/BinaryEngine.ts b/packages/client/src/runtime/core/engines/binary/BinaryEngine.ts index 4e5070e5ac25..ea0d4f94bf28 100644 --- a/packages/client/src/runtime/core/engines/binary/BinaryEngine.ts +++ b/packages/client/src/runtime/core/engines/binary/BinaryEngine.ts @@ -698,7 +698,7 @@ You very likely have the wrong "binaryTarget" defined in the schema.prisma file. if (data.errors) { if (data.errors.length === 1) { - throw prismaGraphQLToJSError(data.errors[0], this.clientVersion!) + throw prismaGraphQLToJSError(data.errors[0], this.clientVersion!, this.config.activeProvider!) } // this case should not happen, as the query engine only returns one error throw new PrismaClientUnknownRequestError(JSON.stringify(data.errors), { clientVersion: this.clientVersion! }) @@ -760,7 +760,7 @@ You very likely have the wrong "binaryTarget" defined in the schema.prisma file. if (Array.isArray(batchResult)) { return batchResult.map((result) => { if (result.errors && result.errors.length > 0) { - return prismaGraphQLToJSError(result.errors[0], this.clientVersion!) + return prismaGraphQLToJSError(result.errors[0], this.clientVersion!, this.config.activeProvider!) } return { data: result, @@ -768,7 +768,7 @@ You very likely have the wrong "binaryTarget" defined in the schema.prisma file. } }) } else { - throw prismaGraphQLToJSError(data.errors[0], this.clientVersion!) + throw prismaGraphQLToJSError(data.errors[0], this.clientVersion!, this.config.activeProvider!) } }) .catch(async (e) => { diff --git a/packages/client/src/runtime/core/engines/data-proxy/DataProxyEngine.ts b/packages/client/src/runtime/core/engines/data-proxy/DataProxyEngine.ts index b53897fd3b8b..e9b980ed8373 100644 --- a/packages/client/src/runtime/core/engines/data-proxy/DataProxyEngine.ts +++ b/packages/client/src/runtime/core/engines/data-proxy/DataProxyEngine.ts @@ -335,7 +335,7 @@ export class DataProxyEngine implements Engine { return batchResult.map((result) => { if ('errors' in result && result.errors.length > 0) { - return prismaGraphQLToJSError(result.errors[0], this.clientVersion!) + return prismaGraphQLToJSError(result.errors[0], this.clientVersion!, this.config.activeProvider!) } return { data: result as T, @@ -389,7 +389,7 @@ export class DataProxyEngine implements Engine { if (json.errors) { if (json.errors.length === 1) { - throw prismaGraphQLToJSError(json.errors[0], this.config.clientVersion!) + throw prismaGraphQLToJSError(json.errors[0], this.config.clientVersion!, this.config.activeProvider!) } else { throw new PrismaClientUnknownRequestError(json.errors, { clientVersion: this.config.clientVersion! }) } diff --git a/packages/client/src/runtime/core/engines/library/LibraryEngine.ts b/packages/client/src/runtime/core/engines/library/LibraryEngine.ts index 09e8ba47e5e0..dbcefc7c2861 100644 --- a/packages/client/src/runtime/core/engines/library/LibraryEngine.ts +++ b/packages/client/src/runtime/core/engines/library/LibraryEngine.ts @@ -532,7 +532,9 @@ You may have to run ${green('prisma generate')} for your changes to take effect. const externalError = this.getExternalAdapterError(error.user_facing_error) - return externalError ? externalError.error : prismaGraphQLToJSError(error, this.config.clientVersion!) + return externalError + ? externalError.error + : prismaGraphQLToJSError(error, this.config.clientVersion!, this.config.activeProvider!) } private getExternalAdapterError(error: RequestError['user_facing_error']): ErrorRecord | undefined { diff --git a/packages/client/src/runtime/core/errors/utils/prismaGraphQLToJSError.ts b/packages/client/src/runtime/core/errors/utils/prismaGraphQLToJSError.ts index 63e2bbfdd69e..d563d8587d57 100644 --- a/packages/client/src/runtime/core/errors/utils/prismaGraphQLToJSError.ts +++ b/packages/client/src/runtime/core/errors/utils/prismaGraphQLToJSError.ts @@ -2,12 +2,15 @@ import { RequestError } from '../../engines/common/types/RequestError' import { PrismaClientKnownRequestError } from '../PrismaClientKnownRequestError' import { PrismaClientUnknownRequestError } from '../PrismaClientUnknownRequestError' +const TOO_MANY_CONNECTIONS_ERROR = 'P2037' + export function prismaGraphQLToJSError( { error, user_facing_error }: RequestError, clientVersion: string, + activeProvider: string, ): PrismaClientKnownRequestError | PrismaClientUnknownRequestError { if (user_facing_error.error_code) { - return new PrismaClientKnownRequestError(user_facing_error.message, { + return new PrismaClientKnownRequestError(getKnownErrorMessage(user_facing_error, activeProvider), { code: user_facing_error.error_code, clientVersion, meta: user_facing_error.meta, @@ -20,3 +23,16 @@ export function prismaGraphQLToJSError( batchRequestIdx: user_facing_error.batch_request_idx, }) } + +function getKnownErrorMessage(userFacingError: RequestError['user_facing_error'], activeProvider: string) { + let message = userFacingError.message + if ( + (activeProvider === 'postgresql' || activeProvider === 'postgres' || activeProvider === 'mysql') && + userFacingError.error_code === TOO_MANY_CONNECTIONS_ERROR + ) { + message += + '\nPrisma Accelerate has built-in connection pooling to prevent such errors: https://pris.ly/client/error-accelerate' + } + + return message +}