relq 1.0.112 → 1.0.113
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/core/pg-family/shared/pg-base.cjs +36 -8
- package/dist/cjs/core/relq-base.cjs +2 -0
- package/dist/cjs/errors/relq-errors.cjs +17 -1
- package/dist/esm/core/pg-family/shared/pg-base.js +36 -8
- package/dist/esm/core/relq-base.js +2 -0
- package/dist/esm/errors/relq-errors.js +17 -1
- package/dist/index.d.ts +1 -0
- package/package.json +1 -1
|
@@ -257,15 +257,24 @@ class PgBase extends relq_base_1.RelqBase {
|
|
|
257
257
|
return;
|
|
258
258
|
this.poolErrorHandler = (err) => {
|
|
259
259
|
const errorCode = err.code;
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
260
|
+
if (isPoolRecoverableError(errorCode)) {
|
|
261
|
+
const logLevel = this.config.logLevel ?? 'info';
|
|
262
|
+
if (logLevel !== 'silent') {
|
|
263
|
+
console.warn('[Relq Pool] Recoverable connection error (pool will auto-recover):', {
|
|
264
|
+
code: errorCode,
|
|
265
|
+
message: err.message,
|
|
266
|
+
action: 'Connection removed from pool, will be replaced on next query'
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
const logLevel = this.config.logLevel ?? 'info';
|
|
272
|
+
if (logLevel !== 'silent') {
|
|
273
|
+
console.error('[Relq Pool] Pool error:', {
|
|
274
|
+
code: errorCode,
|
|
275
|
+
message: err.message,
|
|
276
|
+
});
|
|
263
277
|
}
|
|
264
|
-
console.warn('[Relq Pool] Recoverable connection error (pool will auto-recover):', {
|
|
265
|
-
code: errorCode,
|
|
266
|
-
message: err.message,
|
|
267
|
-
action: 'Connection removed from pool, will be replaced on next query'
|
|
268
|
-
});
|
|
269
278
|
};
|
|
270
279
|
this.poolConnectHandler = () => { };
|
|
271
280
|
this.poolRemoveHandler = () => { };
|
|
@@ -349,3 +358,22 @@ class PgBase extends relq_base_1.RelqBase {
|
|
|
349
358
|
}
|
|
350
359
|
}
|
|
351
360
|
exports.PgBase = PgBase;
|
|
361
|
+
const POOL_RECOVERABLE_NETWORK_CODES = new Set([
|
|
362
|
+
'ECONNRESET', 'ECONNREFUSED', 'ENOTFOUND', 'ESERVFAIL',
|
|
363
|
+
'ETIMEDOUT', 'EPIPE', 'EAI_AGAIN', 'EHOSTUNREACH',
|
|
364
|
+
'ECONNABORTED', 'ENETUNREACH', 'ENETRESET',
|
|
365
|
+
'CONNECTION_LOST', 'PROTOCOL_CONNECTION_LOST',
|
|
366
|
+
]);
|
|
367
|
+
const POOL_RECOVERABLE_PG_CODES = new Set([
|
|
368
|
+
'57P01',
|
|
369
|
+
'57P02',
|
|
370
|
+
'57P03',
|
|
371
|
+
'08006',
|
|
372
|
+
'08001',
|
|
373
|
+
'08004',
|
|
374
|
+
]);
|
|
375
|
+
function isPoolRecoverableError(code) {
|
|
376
|
+
if (!code)
|
|
377
|
+
return true;
|
|
378
|
+
return POOL_RECOVERABLE_NETWORK_CODES.has(code) || POOL_RECOVERABLE_PG_CODES.has(code);
|
|
379
|
+
}
|
|
@@ -14,6 +14,7 @@ class RelqBase {
|
|
|
14
14
|
config;
|
|
15
15
|
schema;
|
|
16
16
|
emitter = new node_events_1.EventEmitter();
|
|
17
|
+
_defaultErrorHandler = () => { };
|
|
17
18
|
columnMappings = new Map();
|
|
18
19
|
initialized = false;
|
|
19
20
|
initPromise;
|
|
@@ -21,6 +22,7 @@ class RelqBase {
|
|
|
21
22
|
constructor(schema, config) {
|
|
22
23
|
this.config = config;
|
|
23
24
|
this.schema = schema;
|
|
25
|
+
this.emitter.on('error', this._defaultErrorHandler);
|
|
24
26
|
if (schema) {
|
|
25
27
|
const log = config.logLevel === 'debug'
|
|
26
28
|
? (...args) => (0, helpers_1.debugLog)(config, ...args)
|
|
@@ -312,7 +312,15 @@ function wrapError(error, context) {
|
|
|
312
312
|
function parsePostgresError(error, sql) {
|
|
313
313
|
const message = error.message || 'Database error';
|
|
314
314
|
const code = error.code;
|
|
315
|
-
if (code
|
|
315
|
+
if (isNetworkErrorCode(code)) {
|
|
316
|
+
return new RelqConnectionError(message, {
|
|
317
|
+
cause: error,
|
|
318
|
+
code,
|
|
319
|
+
host: error.hostname || error.address,
|
|
320
|
+
port: error.port
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
if (code === '57P01' || code === '57P03' || code === '08006' || code === '08001' || code === '08004') {
|
|
316
324
|
return new RelqConnectionError(message, {
|
|
317
325
|
cause: error,
|
|
318
326
|
code,
|
|
@@ -331,3 +339,11 @@ function parsePostgresError(error, sql) {
|
|
|
331
339
|
hint: error.hint
|
|
332
340
|
});
|
|
333
341
|
}
|
|
342
|
+
const NETWORK_ERROR_CODES = new Set([
|
|
343
|
+
'ECONNREFUSED', 'ECONNRESET', 'ENOTFOUND', 'ESERVFAIL',
|
|
344
|
+
'ETIMEDOUT', 'EPIPE', 'EAI_AGAIN', 'EHOSTUNREACH',
|
|
345
|
+
'CONNECTION_LOST', 'PROTOCOL_CONNECTION_LOST',
|
|
346
|
+
]);
|
|
347
|
+
function isNetworkErrorCode(code) {
|
|
348
|
+
return !!code && NETWORK_ERROR_CODES.has(code);
|
|
349
|
+
}
|
|
@@ -220,15 +220,24 @@ export class PgBase extends RelqBase {
|
|
|
220
220
|
return;
|
|
221
221
|
this.poolErrorHandler = (err) => {
|
|
222
222
|
const errorCode = err.code;
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
223
|
+
if (isPoolRecoverableError(errorCode)) {
|
|
224
|
+
const logLevel = this.config.logLevel ?? 'info';
|
|
225
|
+
if (logLevel !== 'silent') {
|
|
226
|
+
console.warn('[Relq Pool] Recoverable connection error (pool will auto-recover):', {
|
|
227
|
+
code: errorCode,
|
|
228
|
+
message: err.message,
|
|
229
|
+
action: 'Connection removed from pool, will be replaced on next query'
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
const logLevel = this.config.logLevel ?? 'info';
|
|
235
|
+
if (logLevel !== 'silent') {
|
|
236
|
+
console.error('[Relq Pool] Pool error:', {
|
|
237
|
+
code: errorCode,
|
|
238
|
+
message: err.message,
|
|
239
|
+
});
|
|
226
240
|
}
|
|
227
|
-
console.warn('[Relq Pool] Recoverable connection error (pool will auto-recover):', {
|
|
228
|
-
code: errorCode,
|
|
229
|
-
message: err.message,
|
|
230
|
-
action: 'Connection removed from pool, will be replaced on next query'
|
|
231
|
-
});
|
|
232
241
|
};
|
|
233
242
|
this.poolConnectHandler = () => { };
|
|
234
243
|
this.poolRemoveHandler = () => { };
|
|
@@ -311,3 +320,22 @@ export class PgBase extends RelqBase {
|
|
|
311
320
|
this.emitter.emit('connect', this.client);
|
|
312
321
|
}
|
|
313
322
|
}
|
|
323
|
+
const POOL_RECOVERABLE_NETWORK_CODES = new Set([
|
|
324
|
+
'ECONNRESET', 'ECONNREFUSED', 'ENOTFOUND', 'ESERVFAIL',
|
|
325
|
+
'ETIMEDOUT', 'EPIPE', 'EAI_AGAIN', 'EHOSTUNREACH',
|
|
326
|
+
'ECONNABORTED', 'ENETUNREACH', 'ENETRESET',
|
|
327
|
+
'CONNECTION_LOST', 'PROTOCOL_CONNECTION_LOST',
|
|
328
|
+
]);
|
|
329
|
+
const POOL_RECOVERABLE_PG_CODES = new Set([
|
|
330
|
+
'57P01',
|
|
331
|
+
'57P02',
|
|
332
|
+
'57P03',
|
|
333
|
+
'08006',
|
|
334
|
+
'08001',
|
|
335
|
+
'08004',
|
|
336
|
+
]);
|
|
337
|
+
function isPoolRecoverableError(code) {
|
|
338
|
+
if (!code)
|
|
339
|
+
return true;
|
|
340
|
+
return POOL_RECOVERABLE_NETWORK_CODES.has(code) || POOL_RECOVERABLE_PG_CODES.has(code);
|
|
341
|
+
}
|
|
@@ -11,6 +11,7 @@ export class RelqBase {
|
|
|
11
11
|
config;
|
|
12
12
|
schema;
|
|
13
13
|
emitter = new EventEmitter();
|
|
14
|
+
_defaultErrorHandler = () => { };
|
|
14
15
|
columnMappings = new Map();
|
|
15
16
|
initialized = false;
|
|
16
17
|
initPromise;
|
|
@@ -18,6 +19,7 @@ export class RelqBase {
|
|
|
18
19
|
constructor(schema, config) {
|
|
19
20
|
this.config = config;
|
|
20
21
|
this.schema = schema;
|
|
22
|
+
this.emitter.on('error', this._defaultErrorHandler);
|
|
21
23
|
if (schema) {
|
|
22
24
|
const log = config.logLevel === 'debug'
|
|
23
25
|
? (...args) => debugLog(config, ...args)
|
|
@@ -290,7 +290,15 @@ export function wrapError(error, context) {
|
|
|
290
290
|
export function parsePostgresError(error, sql) {
|
|
291
291
|
const message = error.message || 'Database error';
|
|
292
292
|
const code = error.code;
|
|
293
|
-
if (code
|
|
293
|
+
if (isNetworkErrorCode(code)) {
|
|
294
|
+
return new RelqConnectionError(message, {
|
|
295
|
+
cause: error,
|
|
296
|
+
code,
|
|
297
|
+
host: error.hostname || error.address,
|
|
298
|
+
port: error.port
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
if (code === '57P01' || code === '57P03' || code === '08006' || code === '08001' || code === '08004') {
|
|
294
302
|
return new RelqConnectionError(message, {
|
|
295
303
|
cause: error,
|
|
296
304
|
code,
|
|
@@ -309,3 +317,11 @@ export function parsePostgresError(error, sql) {
|
|
|
309
317
|
hint: error.hint
|
|
310
318
|
});
|
|
311
319
|
}
|
|
320
|
+
const NETWORK_ERROR_CODES = new Set([
|
|
321
|
+
'ECONNREFUSED', 'ECONNRESET', 'ENOTFOUND', 'ESERVFAIL',
|
|
322
|
+
'ETIMEDOUT', 'EPIPE', 'EAI_AGAIN', 'EHOSTUNREACH',
|
|
323
|
+
'CONNECTION_LOST', 'PROTOCOL_CONNECTION_LOST',
|
|
324
|
+
]);
|
|
325
|
+
function isNetworkErrorCode(code) {
|
|
326
|
+
return !!code && NETWORK_ERROR_CODES.has(code);
|
|
327
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -10023,6 +10023,7 @@ export declare abstract class RelqBase<TSchema = any> {
|
|
|
10023
10023
|
protected config: RelqConfig;
|
|
10024
10024
|
protected schema?: TSchema;
|
|
10025
10025
|
protected readonly emitter: EventEmitter<any>;
|
|
10026
|
+
private readonly _defaultErrorHandler;
|
|
10026
10027
|
protected columnMappings: ColumnMappings;
|
|
10027
10028
|
protected initialized: boolean;
|
|
10028
10029
|
protected initPromise?: Promise<void>;
|