Skip to content

pg-protocol throws an uncatchable error when it loses the connection to PostgreSQL server via TLS #2820

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
yuk2521 opened this issue Sep 26, 2022 · 4 comments

Comments

@yuk2521
Copy link

yuk2521 commented Sep 26, 2022

When the PostgreSQL server gets terminated, an uncatchable error is thrown from pg-protocol with following message

error: terminating connection due to administrator command
    at Parser.parseErrorMessage (/xxx/node_modules/pg-protocol/dist/parser.js:287:98)
    at Parser.handlePacket (/xxx/node_modules/pg-protocol/dist/parser.js:126:29)
    at Parser.parse (/xxx/node_modules/pg-protocol/dist/parser.js:39:38)
    at TLSSocket.<anonymous> (/xxx/node_modules/pg-protocol/dist/index.js:11:42)
    at TLSSocket.emit (node:events:526:28)
    at addChunk (node:internal/streams/readable:315:12)
    at readableAddChunk (node:internal/streams/readable:289:9)
    at TLSSocket.Readable.push (node:internal/streams/readable:228:10)
    at TLSWrap.onStreamRead (node:internal/stream_base_commons:190:23)

It seems that the errors in the on stream data listener here is not handled properly?

stream.on('data', (buffer: Buffer) => parser.parse(buffer, callback))

@yuk2521 yuk2521 changed the title pg-protocol throws an uncatchable error when it loses the connection to postgresql via TLS pg-protocol throws an uncatchable error when it loses the connection to PostgreSQL server via TLS Sep 26, 2022
@charmander
Copy link
Collaborator

const reportStreamError = function (error) {
// errors about disconnections should be ignored during disconnect
if (self._ending && (error.code === 'ECONNRESET' || error.code === 'EPIPE')) {
return
}
self.emit('error', error)
}
this.stream.on('error', reportStreamError)
this.stream.on('close', function () {
self.emit('end')
})
if (!this.ssl) {
return this.attachListeners(this.stream)
}

It’s not uncatchable. You need to add an error listener to any pools and clients you use.

@charmander
Copy link
Collaborator

Canonical issue for improving error ergonomics: #2439 (comment)

@charmander charmander closed this as not planned Won't fix, can't repro, duplicate, stale Sep 26, 2022
@yuk2521
Copy link
Author

yuk2521 commented Sep 26, 2022

Hi @charmander

I'm pretty sure I've added the error listener on the pool as follows

  pool.on('error', (err, client) => {
    logger.error(`Unexpected error on idle client ${client}: ${err}`);
  });

and, all queries are emitted though pool.query. But, still, the error was not caught and the app crashed.

Do you mean the error thrown from the data listener should be caught by the error listener? I've tested with the following example and it fails to catch the error.

const stream = Readable.from(['hi pg']);
stream.on('error', () => {
  console.log('error caught');
});
stream.on('data', () => {
  throw new Error('some error');
});

It produces the error:

$ node main.js
file:///xxx/main.js:8
  throw new Error('some error');
  ^

Error: some error
    at Readable.<anonymous> (file:///xxx/main.js:8:9)
    at Readable.emit (node:events:527:28)
    at Readable.read (node:internal/streams/readable:527:10)
    at flow (node:internal/streams/readable:1011:34)
    at resume_ (node:internal/streams/readable:992:3)
    at processTicksAndRejections (node:internal/process/task_queues:83:21)

@yuk2521
Copy link
Author

yuk2521 commented Sep 26, 2022

Canonical issue for improving error ergonomics: #2439 (comment)

Oh, sorry that I missed this information.

I'll try again with error listeners added to all the connected clients.

Update:
It now works! Thanks for you support @charmander

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants