From f405eabb8f0c60837ddd87310125be74fff8bbd0 Mon Sep 17 00:00:00 2001 From: Arthur Schreiber Date: Wed, 14 Aug 2024 20:51:50 +0200 Subject: [PATCH] feat: set error cause if available (#1649) --- src/connection.ts | 6 +++--- src/errors.ts | 8 ++++---- src/request.ts | 2 +- test/integration/connection-test.js | 12 ++++++++++++ 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/connection.ts b/src/connection.ts index c750c5976..c39c3f7dc 100644 --- a/src/connection.ts +++ b/src/connection.ts @@ -1963,7 +1963,7 @@ class Connection extends EventEmitter { } process.nextTick(() => { - this.emit('connect', new ConnectionError(err.message, 'EINSTLOOKUP')); + this.emit('connect', new ConnectionError(err.message, 'EINSTLOOKUP', { cause: err })); }); }); } @@ -2331,11 +2331,11 @@ class Connection extends EventEmitter { const routingMessage = this.routingData ? ` (redirected from ${this.config.server}${hostPostfix})` : ''; const message = `Failed to connect to ${server}${port}${routingMessage} - ${error.message}`; this.debug.log(message); - this.emit('connect', new ConnectionError(message, 'ESOCKET')); + this.emit('connect', new ConnectionError(message, 'ESOCKET', { cause: error })); } else { const message = `Connection lost - ${error.message}`; this.debug.log(message); - this.emit('error', new ConnectionError(message, 'ESOCKET')); + this.emit('error', new ConnectionError(message, 'ESOCKET', { cause: error })); } this.dispatchEvent('socketError', error); } diff --git a/src/errors.ts b/src/errors.ts index 049826d9e..efbca419e 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -3,8 +3,8 @@ export class ConnectionError extends Error { declare isTransient: boolean | undefined; - constructor(message: string, code?: string) { - super(message); + constructor(message: string, code?: string, options?: ErrorOptions) { + super(message, options); this.code = code; } @@ -20,8 +20,8 @@ export class RequestError extends Error { declare procName: string | undefined; declare lineNumber: number | undefined; - constructor(message: string, code?: string) { - super(message); + constructor(message: string, code?: string, options?: ErrorOptions) { + super(message, options); this.code = code; } diff --git a/src/request.ts b/src/request.ts index 6b6b4f30c..8d54c6c7c 100644 --- a/src/request.ts +++ b/src/request.ts @@ -463,7 +463,7 @@ class Request extends EventEmitter { try { parameter.value = parameter.type.validate(parameter.value, collation); } catch (error: any) { - throw new RequestError('Validation failed for parameter \'' + parameter.name + '\'. ' + error.message, 'EPARAM'); + throw new RequestError('Validation failed for parameter \'' + parameter.name + '\'. ' + error.message, 'EPARAM', { cause: error }); } } } diff --git a/test/integration/connection-test.js b/test/integration/connection-test.js index 77c23f897..a9c206700 100644 --- a/test/integration/connection-test.js +++ b/test/integration/connection-test.js @@ -248,6 +248,10 @@ describe('Initiate Connect Test', function() { try { assert.instanceOf(err, ConnectionError); assert.strictEqual(/** @type {ConnectionError} */(err).code, 'ESOCKET'); + + assert.instanceOf(/** @type {ConnectionError} */(err).cause, Error); + assert.strictEqual(/** @type {Error} */(/** @type {ConnectionError} */(err).cause).message, 'getaddrinfo ENOTFOUND something.invalid'); + assert.strictEqual(connection.connectTimer, undefined); done(); } catch (e) { @@ -277,6 +281,10 @@ describe('Initiate Connect Test', function() { connection.on('connect', (err) => { assert.instanceOf(err, ConnectionError); assert.strictEqual(/** @type {ConnectionError} */(err).code, 'EINSTLOOKUP'); + + assert.instanceOf(/** @type {ConnectionError} */(err).cause, Error); + assert.strictEqual(/** @type {Error} */(/** @type {ConnectionError} */(err).cause).message, 'getaddrinfo ENOTFOUND something.invalid'); + assert.strictEqual(connection.connectTimer, undefined); done(); @@ -310,6 +318,10 @@ describe('Initiate Connect Test', function() { connection.connect(function(err) { assert.instanceOf(err, ConnectionError); assert.strictEqual(/** @type {ConnectionError} */(err).code, 'ESOCKET'); + + assert.instanceOf(/** @type {ConnectionError} */(err).cause, Error); + console.log(/** @type {ConnectionError} */(err).cause); + assert.include(/** @type {Error} */(/** @type {ConnectionError} */(err).cause).message, 'no ciphers available'); }); connection.on('end', function() {