kysely
kysely copied to clipboard
Uncatchable connection errors in MS SQL
This error happens specifically when connecting to a SQL Server with encryption disabled, without explicity set encrypt: false in Tedious.
It will results in two separate errors.
-
[ESOCKET] socket hang up
Error: Failed to connect to [REDACTED] - socket hang up{ "code": "ESOCKET", "stack": [ "Error: Failed to connect to [REDACTED] - socket hang up", " at Connection2.socketError (REDACTED)", " at Connection2.socketEnd (REDACTED)", " at Socket.<anonymous> (REDACTED)", " at Socket.emit (node:events:530:35)", " at endReadableNT (node:internal/streams/readable:1698:12)", " at process.processTicksAndRejections (node:internal/process/task_queues:90:21)" ] }The first error can be caught with
propagateCreateErrorenabled inTarn. -
[ESOCKET] Connection lost - unexpected end of message stream
{ "errorType": "Error", "errorMessage": "Connection lost - unexpected end of message stream", "code": "ESOCKET", "stack": [ "Error: Connection lost - unexpected end of message stream", " at Connection2.socketError ([REDACTED])", " at [REDACTED]", " at process.processTicksAndRejections (node:internal/process/task_queues:105:5)" ] }The second error is uncatchable thus always exits the program.
Expected Results
Exactly one error is caught when the first connection is made via any query executions, for example:
try {
await sql`SELECT 1`.execute(db);
} catch(e) {
console.error("Connection Error", e);
}
console.log("This continue to work");
Workaround
Attach an error event listener to the Tedious connection.
const db = new Kysely({
dialect: new MssqlDialect({
tarn: {
...Tarn,
options: {
// This allows the first error to be caught
propagateCreateError: true,
},
},
tedious: {
...Tedious,
connectionFactory: () => {
const connection = new Tedious.Connection(...);
connection.on("error", (error) => {
// This catches/suppresses the second error
});
return connection;
},
},
}),
});