From a925be97a6e21c58b2941ba5e11be9eeb91ac30c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Wadas?= Date: Thu, 5 Sep 2019 16:05:23 +0200 Subject: [PATCH] feat: add postgres pool error handler (#4474) Add option to customize pool error handling. Users can decide to log these errors with higher level (eg. error), crash application or reconnect. --- docs/connection-options.md | 4 ++++ src/driver/cockroachdb/CockroachConnectionOptions.ts | 7 +++++++ src/driver/cockroachdb/CockroachDriver.ts | 5 ++++- src/driver/postgres/PostgresConnectionOptions.ts | 7 +++++++ src/driver/postgres/PostgresDriver.ts | 5 ++++- src/driver/sqlserver/SqlServerConnectionOptions.ts | 7 +++++++ src/driver/sqlserver/SqlServerDriver.ts | 4 +++- 7 files changed, 36 insertions(+), 3 deletions(-) diff --git a/docs/connection-options.md b/docs/connection-options.md index c222aaa24c..5a6479959a 100644 --- a/docs/connection-options.md +++ b/docs/connection-options.md @@ -180,6 +180,8 @@ See [SSL options](https://github.com/mysqljs/mysql#ssl-options). * `uuidExtension` - The Postgres extension to use when generating UUIDs. Defaults to `uuid-ossp`. Can be changed to `pgcrypto` if the `uuid-ossp` extension is unavailable. +* `poolErrorHandler` - A function that get's called when underlying pool emits `'error'` event. Takes single parameter (error instance) and defaults to logging with `warn` level. + ## `sqlite` connection options * `database` - Database path. For example "./mydb.sql" @@ -258,6 +260,8 @@ See [SSL options](https://github.com/mysqljs/mysql#ssl-options). * `pool.idleTimeoutMillis` - the minimum amount of time that an object may sit idle in the pool before it is eligible for eviction due to idle time. Supersedes `softIdleTimeoutMillis`. Default: `30000`. + * `pool.errorHandler` - A function that get's called when underlying pool emits `'error'` event. Takes single parameter (error instance) and defaults to logging with `warn` level. + * `options.fallbackToDefaultDb` - By default, if the database requestion by `options.database` cannot be accessed, the connection will fail with an error. However, if `options.fallbackToDefaultDb` is set to `true`, then the user's default database will be used instead (Default: `false`). diff --git a/src/driver/cockroachdb/CockroachConnectionOptions.ts b/src/driver/cockroachdb/CockroachConnectionOptions.ts index 71e1d998f1..8dbd8fc151 100644 --- a/src/driver/cockroachdb/CockroachConnectionOptions.ts +++ b/src/driver/cockroachdb/CockroachConnectionOptions.ts @@ -33,4 +33,11 @@ export interface CockroachConnectionOptions extends BaseConnectionOptions, Cockr }; + + /* + * Function handling errors thrown by drivers pool. + * Defaults to logging error with `warn` level. + */ + readonly poolErrorHandler?: (err: any) => any; + } diff --git a/src/driver/cockroachdb/CockroachDriver.ts b/src/driver/cockroachdb/CockroachDriver.ts index 31b0f298fd..188be7d8f9 100644 --- a/src/driver/cockroachdb/CockroachDriver.ts +++ b/src/driver/cockroachdb/CockroachDriver.ts @@ -710,11 +710,14 @@ export class CockroachDriver implements Driver { // create a connection pool const pool = new this.postgres.Pool(connectionOptions); const { logger } = this.connection; + + const poolErrorHandler = options.poolErrorHandler || ((error: any) => logger.log("warn", `Postgres pool raised an error. ${error}`)); + /* Attaching an error handler to pool errors is essential, as, otherwise, errors raised will go unhandled and cause the hosting app to crash. */ - pool.on("error", (error: any) => logger.log("warn", `Postgres pool raised an error. ${error}`)); + pool.on("error", poolErrorHandler); return new Promise((ok, fail) => { pool.connect((err: any, connection: any, release: Function) => { diff --git a/src/driver/postgres/PostgresConnectionOptions.ts b/src/driver/postgres/PostgresConnectionOptions.ts index dd49791a40..aa70411217 100644 --- a/src/driver/postgres/PostgresConnectionOptions.ts +++ b/src/driver/postgres/PostgresConnectionOptions.ts @@ -39,4 +39,11 @@ export interface PostgresConnectionOptions extends BaseConnectionOptions, Postgr * If uuid-ossp is selected, TypeORM will use the uuid_generate_v4() function from this extension. */ readonly uuidExtension?: "pgcrypto" | "uuid-ossp"; + + + /* + * Function handling errors thrown by drivers pool. + * Defaults to logging error with `warn` level. + */ + readonly poolErrorHandler?: (err: any) => any; } diff --git a/src/driver/postgres/PostgresDriver.ts b/src/driver/postgres/PostgresDriver.ts index 74f631e3c4..4603027d1b 100644 --- a/src/driver/postgres/PostgresDriver.ts +++ b/src/driver/postgres/PostgresDriver.ts @@ -894,11 +894,14 @@ export class PostgresDriver implements Driver { // create a connection pool const pool = new this.postgres.Pool(connectionOptions); const { logger } = this.connection; + + const poolErrorHandler = options.poolErrorHandler || ((error: any) => logger.log("warn", `Postgres pool raised an error. ${error}`)); + /* Attaching an error handler to pool errors is essential, as, otherwise, errors raised will go unhandled and cause the hosting app to crash. */ - pool.on("error", (error: any) => logger.log("warn", `Postgres pool raised an error. ${error}`)); + pool.on("error", poolErrorHandler); return new Promise((ok, fail) => { pool.connect((err: any, connection: any, release: Function) => { diff --git a/src/driver/sqlserver/SqlServerConnectionOptions.ts b/src/driver/sqlserver/SqlServerConnectionOptions.ts index e6bd2dac94..00d71eb401 100644 --- a/src/driver/sqlserver/SqlServerConnectionOptions.ts +++ b/src/driver/sqlserver/SqlServerConnectionOptions.ts @@ -106,6 +106,12 @@ export interface SqlServerConnectionOptions extends BaseConnectionOptions, SqlSe * to idle time. Supercedes softIdleTimeoutMillis Default: 30000 */ readonly idleTimeoutMillis?: number; + + /* + * Function handling errors thrown by drivers pool. + * Defaults to logging error with `warn` level. + */ + readonly errorHandler?: (err: any) => any; }; /** @@ -271,4 +277,5 @@ export interface SqlServerConnectionOptions extends BaseConnectionOptions, SqlSe }; + } diff --git a/src/driver/sqlserver/SqlServerDriver.ts b/src/driver/sqlserver/SqlServerDriver.ts index a961623b9d..c06b911fe6 100644 --- a/src/driver/sqlserver/SqlServerDriver.ts +++ b/src/driver/sqlserver/SqlServerDriver.ts @@ -749,11 +749,13 @@ export class SqlServerDriver implements Driver { const pool = new this.mssql.ConnectionPool(connectionOptions); const { logger } = this.connection; + + const poolErrorHandler = (options.pool && options.pool.errorHandler) || ((error: any) => logger.log("warn", `MSSQL pool raised an error. ${error}`)); /* Attaching an error handler to pool errors is essential, as, otherwise, errors raised will go unhandled and cause the hosting app to crash. */ - pool.on("error", (error: any) => logger.log("warn", `MSSQL pool raised an error. ${error}`)); + pool.on("error", poolErrorHandler); const connection = pool.connect((err: any) => { if (err) return fail(err);