sidorares / sidorares/node-mysql2

relying on connection.end() callback is causing process to exit early

Open
#450 10 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
TypeScript
Stars
4.4k
Forks
680
Avg merge
9h 7m
Merged PRs (30d)
59

Description

Here is the code:

const mysql = require('mysql2');
const Promise = require('bluebird');

const config = {
  "database": "showtime",
  "host": "127.0.0.1",
  "password": "your-database",
  "port": "3306",
  "user": "root"
};

+ const makeItWork = true;

const createConnection = (options = {}) => {
  options.namedPlaceholders = true;
  options.decimalNumbers = false;

  return new Promise((resolve, reject) => {
    const connection = mysql.createConnection(options);

    connection.once('connect', () => {
      resolve(connection);
    });

    connection.once('error', (error) => {
      reject(error);
    });
  });
};

const createDisposableConnection = (connectionOptions) => {
  return createConnection(connectionOptions)
    .then((connection) => {
      return connection;
    })
    .disposer((connection) => {
      console.log('Disposing of connection...');
      return Promise
        .fromCallback((callback) => {
+          if (makeItWork) {
+            connection.end();
+
+            callback();
+          } else {
+            connection.end(callback);
+          }
        })
        .then(() => {
          console.log('This is never reached. (createDisposableConnection)');
        });
    });
};

Promise
  .using(createDisposableConnection(config), (connection) => {
    return new Promise((resolve, reject) => {
      connection
        .query('SELECT `id`, `nid`, ST_X(`coordinates`) `longitude`, ST_Y(`coordinates`) `latitude` FROM `location` WHERE `coordinates` != POINT(0, 0) ORDER BY `google_places_lookup_at` ASC')
        .on('result', (row) => {
          console.log('Hello');

          connection.pause();

          reject(new Error('Continue... 0'));
        })
    })
    .catch(() => {
      console.log('I am caught!');

      throw new Error('Continue... 1');
    });
  })
  .then(() => {
    console.log('This is never called. (this)');
  })
  .catch(() => {
    console.log('This is never called. (catch)');
  });

Here is the program output when makeItWork = true:

Hello
I am caught!
Disposing of connection...
This is never reached. (createDisposableConnection)
This is never called. (catch)

Here is the program output when makeItWork = false:

Hello
I am caught!
Disposing of connection...

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the supplied createDisposableConnection disposer and compare the connection.end(callback) path with the immediate-callback path when makeItWork is true. Run the reproduction against node-mysql2 and Bluebird, then trace whether the process exits before the disposer promise settles. Done means the callback behavior and early process exit are explained with a reproducible result.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, mysql, node.js
Domain
backend, database
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.