Skip to content

Zalgo bug #1147

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
rogierschouten opened this issue Jul 9, 2015 · 5 comments
Closed

Zalgo bug #1147

rogierschouten opened this issue Jul 9, 2015 · 5 comments
Assignees
Labels

Comments

@rogierschouten
Copy link

Seen in v2.5.3

The callback to connection.query() is sometimes called synchronously in case of an error. In general, one should not call callbacks both synchronously and a-synchronously (google for "releasing Zalgo").

In my case, it resulted in a type error because I reset some variables inside the callback that I make use of directly after calling the query() method, i.e.

function doQuery() {
  var myVar = { foo: "bar" };
  connection.destroy();
  connection.query("SELECT * FROM mytable", function() {
     myVar = undefined;
  });
  console.log(myVar.foo); // myVar is undefined
}

This does not happen if the callback is always called a-synchronously but apparently there are scenarios where it isn't.

It occurred when I accidentally called query() after calling destroy().

@dougwilson
Copy link
Member

Hi @rogierschouten to make sure we're looking at the same Zalgo, can you really quick take your code and swap the myVar = undefined with a console.trace() and paste the trace here?

@rogierschouten
Copy link
Author

Here you go...

var mysql = require("mysql");

var connection = mysql.createConnection({
  host     : 'localhost',
  user     : 'me',
  password : 'password',
  database : 'my_db'
});

function doTheQuery() {
  var myVar = { foo: "bar" };
  connection.destroy();
  connection.query("SELECT * FROM mytable", function() {
     myVar = undefined;
  });
  console.trace(myVar.foo); // myVar is undefined
}

connection.connect(function(err) {
  if (err) {
    console.error('error connecting: ' + err.stack);
    return;
  }

  console.log('connected as id ' + connection.threadId);

  doTheQuery();

});

Output trace:

$ node test.js
connected as id 8912

c:\Source\eXLent_master\exlent\node_modules\mysql\lib\protocol\Parser.js:82
        throw err;
              ^
TypeError: Cannot read property 'foo' of undefined
    at doTheQuery (c:\Source\eXLent_master\exlent\temp\test.js:16:22)
    at Handshake._callback (c:\Source\eXLent_master\exlent\temp\test.js:27:3)
    at Handshake.Sequence.end (c:\Source\eXLent_master\exlent\node_modules\mysql\lib\protocol\sequences\Sequence.js:96:24)
    at Handshake.Sequence.OkPacket (c:\Source\eXLent_master\exlent\node_modules\mysql\lib\protocol\sequences\Sequence.js:105:8)
    at Protocol._parsePacket (c:\Source\eXLent_master\exlent\node_modules\mysql\lib\protocol\Protocol.js:271:23)
    at Parser.write (c:\Source\eXLent_master\exlent\node_modules\mysql\lib\protocol\Parser.js:77:12)
    at Protocol.write (c:\Source\eXLent_master\exlent\node_modules\mysql\lib\protocol\Protocol.js:39:16)
    at Socket.<anonymous> (c:\Source\eXLent_master\exlent\node_modules\mysql\lib\Connection.js:96:28)
    at Socket.emit (events.js:95:17)
    at Socket.<anonymous> (_stream_readable.js:765:14)

@dougwilson
Copy link
Member

Hi @rogierschouten to make sure we're looking at the same Zalgo, can you really quick take your code and swap the myVar = undefined with a console.trace() and paste the trace here? I see you placed the console.trace() in the wrong place. I need it to be where the myVar = undefined is in the code.

@rogierschouten
Copy link
Author

This better?

var mysql = require("mysql");

var connection = mysql.createConnection({
  host     : 'localhost',
  user     : 'me',
  password : 'password',
  database : 'my_db'
});

function doTheQuery() {
  var myVar = { foo: "bar" };
  connection.destroy();
  connection.query("SELECT * FROM mytable", function() {
    console.trace();
    myVar = undefined;
  });
  // console.log(myVar.foo); // myVar is undefined
}

connection.connect(function(err) {
  if (err) {
    console.error('error connecting: ' + err.stack);
    return;
  }

  console.log('connected as id ' + connection.threadId);

  doTheQuery();

});

$ node test.js
connected as id 9945
Trace
    at Query._callback (c:\Source\eXLent_master\exlent\temp\test.js:14:10)
    at Query.Sequence.end (c:\Source\eXLent_master\exlent\node_modules\mysql\lib\protocol\sequences\Sequence.js:96:24)
    at Protocol._validateEnqueue (c:\Source\eXLent_master\exlent\node_modules\mysql\lib\protocol\Protocol.js:218:6)
    at Protocol._enqueue (c:\Source\eXLent_master\exlent\node_modules\mysql\lib\protocol\Protocol.js:129:13)
    at Connection.query (c:\Source\eXLent_master\exlent\node_modules\mysql\lib\Connection.js:201:25)
    at doTheQuery (c:\Source\eXLent_master\exlent\temp\test.js:13:14)
    at Handshake._callback (c:\Source\eXLent_master\exlent\temp\test.js:28:3)
    at Handshake.Sequence.end (c:\Source\eXLent_master\exlent\node_modules\mysql\lib\protocol\sequences\Sequence.js:96:24)
    at Handshake.Sequence.OkPacket (c:\Source\eXLent_master\exlent\node_modules\mysql\lib\protocol\sequences\Sequence.js:105:8)
    at Protocol._parsePacket (c:\Source\eXLent_master\exlent\node_modules\mysql\lib\protocol\Protocol.js:271:23)

@dougwilson
Copy link
Member

Yes, thank you!

@dougwilson dougwilson added the bug label Jul 9, 2015
@dougwilson dougwilson self-assigned this Jul 9, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

2 participants