Summary
PostgresExternalService.subscribe() in @skip-adapter/postgres has three related issues around error handling that can leave the adapter in an inconsistent state or crash the process.
Location
@skip-adapter/postgres — src/index.ts, class PostgresExternalService, subscribe() method
Issues
1. open_instances.add() called before queries succeed
The instance is added to open_instances before the trigger/function/listen queries run. If any query fails, the instance is marked as set up but the trigger was never created. Subsequent calls to subscribe skip setup because open_instances.has(instance) returns true.
// Current code (broken)
if (!this.open_instances.has(instance)) {
this.open_instances.add(instance); // ← marked before queries
await this.client.query(/* CREATE FUNCTION ... */);
await this.client.query(/* LISTEN ... */);
await this.client.query(/* CREATE TRIGGER ... */);
}
Fix: move this.open_instances.add(instance) after all three queries succeed.
2. No error handler on pg.Client
If the Postgres connection emits an error event (e.g. server restart, network drop), node's pg.Client will crash the process with an unhandled error. Additionally, open_instances retains stale entries so the adapter won't re-create triggers after reconnection.
Fix: add this.client.on("error", ...) in the constructor that logs the error and clears open_instances.
3. No try-catch around setupPgNotify / initData
Both setupPgNotify() and initData() can throw (e.g. table doesn't exist yet, permission error). An unhandled error in setupPgNotify crashes the process. An unhandled error in initData propagates without context.
Fix: wrap both in try-catch with logging.
How to reproduce
For issue 1:
- Start a Skip service with a Postgres external service
- Make the
CREATE TRIGGER query fail (e.g. the table doesn't exist yet at trigger creation time)
- Restart the service —
subscribe() skips setup because open_instances still has the instance
- No trigger is ever created; real-time updates never arrive
For issue 2:
- Start a Skip service connected to Postgres
- Restart Postgres or drop the network connection
- The process crashes with an unhandled
error event from pg.Client
Version
@skip-adapter/postgres@0.0.19
Summary
PostgresExternalService.subscribe()in@skip-adapter/postgreshas three related issues around error handling that can leave the adapter in an inconsistent state or crash the process.Location
@skip-adapter/postgres—src/index.ts, classPostgresExternalService,subscribe()methodIssues
1.
open_instances.add()called before queries succeedThe instance is added to
open_instancesbefore the trigger/function/listen queries run. If any query fails, the instance is marked as set up but the trigger was never created. Subsequent calls tosubscribeskip setup becauseopen_instances.has(instance)returnstrue.Fix: move
this.open_instances.add(instance)after all three queries succeed.2. No error handler on pg.Client
If the Postgres connection emits an
errorevent (e.g. server restart, network drop), node'spg.Clientwill crash the process with an unhandled error. Additionally,open_instancesretains stale entries so the adapter won't re-create triggers after reconnection.Fix: add
this.client.on("error", ...)in the constructor that logs the error and clearsopen_instances.3. No try-catch around setupPgNotify / initData
Both
setupPgNotify()andinitData()can throw (e.g. table doesn't exist yet, permission error). An unhandled error insetupPgNotifycrashes the process. An unhandled error ininitDatapropagates without context.Fix: wrap both in try-catch with logging.
How to reproduce
For issue 1:
CREATE TRIGGERquery fail (e.g. the table doesn't exist yet at trigger creation time)subscribe()skips setup becauseopen_instancesstill has the instanceFor issue 2:
errorevent frompg.ClientVersion
@skip-adapter/postgres@0.0.19