Skip to content

Commit

Permalink
Fail gracefully when connecting to other database (#3026)
Browse files Browse the repository at this point in the history
* Fail gracefully when connecting to other SGDB vendor

* Make test more flexible. Adjust error wording to match native better.

---------

Co-authored-by: Brian Carlson <brian.m.carlson@gmail.com>
  • Loading branch information
romain-gilliotte and brianc committed Sep 15, 2023
1 parent d21cc09 commit b1a8947
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 1 deletion.
2 changes: 1 addition & 1 deletion packages/pg-protocol/src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ export class Parser {
case MessageCodes.CopyData:
return this.parseCopyData(offset, length, bytes)
default:
assert.fail(`unknown message code: ${code.toString(16)}`)
return new DatabaseError('received invalid response: ' + code.toString(16), length, 'error')
}
}

Expand Down
63 changes: 63 additions & 0 deletions packages/pg/test/integration/gh-issues/2627-tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
'use strict'
const net = require('net')
const helper = require('./../test-helper')

const suite = new helper.Suite()

const options = {
host: 'localhost',
port: Math.floor(Math.random() * 2000) + 2000,
connectionTimeoutMillis: 2000,
user: 'not',
database: 'existing',
}

// This is the content of the packets sent by a MySQL server during the handshake.
// Those were captured with the `mysql:8.0.33` docker image.
const MySqlHandshake = Buffer.from(
'SgAAAAo4LjAuMjgAHwAAAB4dKyUJZ2p6AP///wIA/98VAAAAAAAAAAAA' +
'AAo1YiNJajgKKGkpfgBjYWNoaW5nX3NoYTJfcGFzc3dvcmQAIQAAAf+EBC' +
'MwOFMwMUdvdCBwYWNrZXRzIG91dCBvZiBvcmRlcg==',
'base64'
)

const serverWithInvalidResponse = (port, callback) => {
const sockets = new Set()

const server = net.createServer((socket) => {
socket.write(MySqlHandshake)

// This server sends an invalid response which should throw in pg-protocol
sockets.add(socket)
})

let closing = false
const closeServer = (done) => {
if (closing) return
closing = true

server.close(done)
for (const socket of sockets) {
socket.destroy()
}
}

server.listen(port, options.host, () => callback(closeServer))
}

suite.test('client should fail to connect', (done) => {
serverWithInvalidResponse(options.port, (closeServer) => {
const client = new helper.Client(options)

client
.connect()
.then(() => {
done(new Error('Expected client.connect() to fail'))
})
.catch((err) => {
assert(err)
assert(err.message.includes('invalid response'))
closeServer(done)
})
})
})

0 comments on commit b1a8947

Please sign in to comment.