From 72bcdac8973acc284c6924e17a3283371bc05fb7 Mon Sep 17 00:00:00 2001 From: ci <61233757+MaxAake@users.noreply.github.com> Date: Wed, 30 Jul 2025 11:16:20 +0200 Subject: [PATCH 1/2] introduce StatusFinder functions --- packages/core/src/error.ts | 28 ++++++++++++++++ packages/core/test/error.test.ts | 34 ++++++++++++++++++++ packages/neo4j-driver-deno/lib/core/error.ts | 28 ++++++++++++++++ 3 files changed, 90 insertions(+) diff --git a/packages/core/src/error.ts b/packages/core/src/error.ts index a1df60d1d..35b203c87 100644 --- a/packages/core/src/error.ts +++ b/packages/core/src/error.ts @@ -150,6 +150,34 @@ class GQLError extends Error { this.name = 'GQLError' } + /** + * Returns whether a given GqlStatus code can be found in the cause chain of the error (including the error itself). + * + * @param {string} gqlStatus the GqlStatus code to find + * @returns {boolean} + */ + containsGqlCause (gqlStatus: string): boolean { + return this.findByGqlStatus(gqlStatus) !== undefined + } + + /** + * Returns the first error in the cause chain (including the error itself) with a given GqlStatus code. + * Returns undefined if the GqlStatus code is not present anywhere in the chain. + * + * @param {string} gqlStatus the GqlStatus code to find + * @returns {GQLError | Neo4jError | undefined} + */ + findByGqlStatus (gqlStatus: string): GQLError | Neo4jError | undefined { + if (this.gqlStatus === gqlStatus) { + return this + } + if (this.cause !== undefined && (this.cause instanceof GQLError || this.cause instanceof Neo4jError)) { + return this.cause.findByGqlStatus(gqlStatus) + } + + return undefined + } + /** * The json string representation of the diagnostic record. * The goal of this method is provide a serialized object for human inspection. diff --git a/packages/core/test/error.test.ts b/packages/core/test/error.test.ts index 8f06745a6..a8d29b710 100644 --- a/packages/core/test/error.test.ts +++ b/packages/core/test/error.test.ts @@ -16,6 +16,7 @@ */ import { Neo4jError, + GQLError, isRetriableError, newError, newGQLError, @@ -199,8 +200,41 @@ describe('Neo4jError', () => { expect(Neo4jError.isRetriable(error)).toBe(false) }) }) + + describe('.containsGqlCause()', () => { + it.each([ + [createNestedErrors(0), 'cause0', false], + [createNestedErrors(0), 'root', true], + [createNestedErrors(10), 'cause8', true], + [createNestedErrors(10), 'cause11', false] + ])('should correctly identify if GQLStatus is present in cause chain', (error, status, expectedResult) => { + expect(error.containsGqlCause(status)).toBe(expectedResult) + }) + }) + + describe('.findByGqlStatus()', () => { + it.each([ + [createNestedErrors(0), 'cause0', undefined], + [createNestedErrors(0), 'root', 'root'], + [createNestedErrors(10), 'cause8', '8cause'], + [createNestedErrors(10), 'cause11', undefined] + ])('should correctly find error in cause chain', (error, status, expectedMessage) => { + expect(error.findByGqlStatus(status)?.message).toBe(expectedMessage) + }) + }) }) +function createNestedErrors (causes: number): Neo4jError { + const error = new Neo4jError('root', '', 'root', '') + let current: Neo4jError | GQLError = error + for (let i = 0; i < causes; i++) { + const cause = new GQLError(i.toString() + 'cause', 'cause' + i.toString(), '') + current.cause = cause + current = cause + } + return error +} + function getRetriableErrorsFixture (): Array<[Neo4jError]> { return getRetriableCodes().map(code => [newError('message', code)]) } diff --git a/packages/neo4j-driver-deno/lib/core/error.ts b/packages/neo4j-driver-deno/lib/core/error.ts index 43a38216f..1e3bbfb53 100644 --- a/packages/neo4j-driver-deno/lib/core/error.ts +++ b/packages/neo4j-driver-deno/lib/core/error.ts @@ -150,6 +150,34 @@ class GQLError extends Error { this.name = 'GQLError' } + /** + * Returns whether a given GqlStatus code can be found in the cause chain of the error (including the error itself). + * + * @param {string} gqlStatus the GqlStatus code to find + * @returns {boolean} + */ + containsGqlCause(gqlStatus: string) : boolean { + return this.findByGqlStatus(gqlStatus) !== undefined + } + + /** + * Returns the first error in the cause chain (including the error itself) with a given GqlStatus code. + * Returns undefined if the GqlStatus code is not present anywhere in the chain. + * + * @param {string} gqlStatus the GqlStatus code to find + * @returns {GQLError | Neo4jError | undefined} + */ + findByGqlStatus(gqlStatus: string) : GQLError | Neo4jError | undefined { + if (this.gqlStatus === gqlStatus) { + return this + } + if (this.cause !== undefined && (this.cause instanceof GQLError || this.cause instanceof Neo4jError)) { + return this.cause.findByGqlStatus(gqlStatus) + } + + return undefined + } + /** * The json string representation of the diagnostic record. * The goal of this method is provide a serialized object for human inspection. From 947b1d6a614c60f585894baeb50dfc18e03b101d Mon Sep 17 00:00:00 2001 From: ci <61233757+MaxAake@users.noreply.github.com> Date: Wed, 30 Jul 2025 11:17:15 +0200 Subject: [PATCH 2/2] deno sync --- packages/neo4j-driver-deno/lib/core/error.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/neo4j-driver-deno/lib/core/error.ts b/packages/neo4j-driver-deno/lib/core/error.ts index 1e3bbfb53..deccb0b07 100644 --- a/packages/neo4j-driver-deno/lib/core/error.ts +++ b/packages/neo4j-driver-deno/lib/core/error.ts @@ -152,22 +152,22 @@ class GQLError extends Error { /** * Returns whether a given GqlStatus code can be found in the cause chain of the error (including the error itself). - * + * * @param {string} gqlStatus the GqlStatus code to find * @returns {boolean} */ - containsGqlCause(gqlStatus: string) : boolean { + containsGqlCause (gqlStatus: string): boolean { return this.findByGqlStatus(gqlStatus) !== undefined } /** * Returns the first error in the cause chain (including the error itself) with a given GqlStatus code. * Returns undefined if the GqlStatus code is not present anywhere in the chain. - * + * * @param {string} gqlStatus the GqlStatus code to find * @returns {GQLError | Neo4jError | undefined} */ - findByGqlStatus(gqlStatus: string) : GQLError | Neo4jError | undefined { + findByGqlStatus (gqlStatus: string): GQLError | Neo4jError | undefined { if (this.gqlStatus === gqlStatus) { return this }