Skip to content

Connection errors are not propagated to the query stream #1847

@dsech

Description

@dsech

Sample code:

import { createPool } from "mysql2";

const connection = createPool({
    host: 'localhost',
    user: 'user',
    password: 'pass',
  });
try {
  for await (const row of connection.query("SELECT * FROM big_table").stream()) {
    // handle row here
  }
} catch (e) {
  // connection errors are not caught here
  console.log('caught error', e);
}

If any connection errors occur during the command execution, they will not be caught while iterating over the rows.

After investigation I found the issue to be in Connection.notifyError here

if (this._command && this._command.onResult) {
this._command.onResult(err);
this._command = null;
// connection handshake is special because we allow it to be implicit
// if error happened during handshake, but there are others commands in queue
// then bubble error to other commands and not to connection
} else if (

From what I see, the error will be passed to the command only if the command was executed with a callback.

A solution that seems to fix the issue is to also emit the error to the command like this:

if (this._command) {
  this._command.emit('error', err);
}

With the above change the error will be emitted to the command, and will also be thrown when iterating over the stream.

Can be reproduced by running a slow query like SELECT SLEEP(30) and then issue a KILL "connection id"

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions