0

I have this code here

io.on("connection", function(socket){

    //other methods where emit works

    socket.on("login", function(data) {
        try {
            pg.connect(conString, function(err, con) {
                var query = con.query("SELECT * FROM accounts WHERE username" +
                "='" + data.usn + "';");
                query.on("row", function(row, result) result.addRow(row); });
                query.on("end", function(result) {
                    if (sha512(data.pwd, result.rows[0].salt).hash ===
                        result.rows[0].password) {

                        socket.emit("loginResponse", { status: "Success" });

                        console.log("I GOT UP TO HERE WITHOUT EMITTING! WTF?");
                        console.log(sha512(data.pwd,result.rows[0].salt).hash);
                        console.log(result.rows[0].password);
                    }
                });
            });
        } catch (ex) { console.log(ex); }
    });
});

Obviously, on the client side, I have something like this:

socket.on("loginResponse", function(data) {
    alert(data.status);
});

However, whenever I try to log in successfully, my server doesn't emit anything to the client, i.e. I will see the printed lines on my terminal but the client doesn't get a response from the server. I've been baffled by this. I have another function which touches the PostgreSQL driver and emits successfully, but this one doesn't. Does anyone know why this is the case?

  • I dont see any emits there... only a on function that has a emit inside... plus in the client side you need to inclucde var societ = io.connect(); – amanuel2 Feb 20 '16 at 19:11
  • Yes, I already have a declaration in the client code that connects to my server. I'm trying to emit the loginResponse, but it's not being called. – goodpoutine Feb 20 '16 at 19:13
  • When does the login gets emitted? – Tushar Arora Feb 20 '16 at 19:31
  • If I add socket.emit("loginResponse", { status: "Error" }); right after the try block, then the client gets the response. But for some weird reason which I've exhaustively tried finding a solution for, the inner emit isn't being called at all. Also, the login request is sent from the client as soon as they submit a form. I verified that this route is happening correctly because I can see the console.log calls in my terminal. – goodpoutine Feb 20 '16 at 19:33

1 Answers1

0

You have a bug in your code. Asynchronous functions should never be written inside try/catch.

try {
    setTimeout(function() {
        do_something_that_throws();
    }, 1000);
}
catch (e) {
    alert("You won't see this!");
}

The problem is that the control flow leaves the try block before do_something_that_throws() gets executed, so the error thrown inside the callback never gets catched.

socket.on("login", function(data) {    
  pg.connect(conString, function(err, con) {
    if(err) {
      // handle error
    }
    var query = con.query("SELECT * FROM accounts WHERE username" +
    "='" + data.usn + "';");
    query.on("row", function(row, result) result.addRow(row); });
    query.on("end", function(result) {
      if (sha512(data.pwd, result.rows[0].salt).hash ===
        result.rows[0].password) {

        socket.emit("loginResponse", { status: "Success" });

        console.log("I GOT UP TO HERE WITHOUT EMITTING! WTF?");
        console.log(sha512(data.pwd,result.rows[0].salt).hash);
        console.log(result.rows[0].password);
      }
    });
  });
});

Try this approach and let me know if its working.

Tushar Arora
  • 1,106
  • 2
  • 10
  • 22
  • I tried your solution, but I'm still getting the same problem: socket.emit() is being ignored. If I put this socket.emit() elsewhere in a sensible place where it can be called, then it works properly, so I know there's nothing wrong on the client side. Here's what I tried: http://i.imgur.com/q2eiwW4.jpg – goodpoutine Feb 20 '16 at 20:02
  • You should debug it using another event. For example - socket.emit('test', {status: "Success"}); Now emit loginResponse from socket.on of test event. – Tushar Arora Feb 20 '16 at 20:18
  • So I've tried several workarounds and none of them work: emitting with a different name, calling other methods that emit the message, emitting a different response. It seems as though query.on("end") ignores the socket.emit() call and any function that calls socket.emit(), despite it printing out those three lines. – goodpoutine Feb 20 '16 at 20:31
  • Interestingly, when I try this: http://i.imgur.com/6k9Swwi.jpg the socket.emit() is called, but with the wrong data despite a successful login, i.e. it should be sending "Success" but it's sending "foo" even though the three lines were printed. – goodpoutine Feb 20 '16 at 20:41
  • Have a look at this - http://gonzalo123.com/2012/05/07/asynchronous-queries-to-relational-databases-from-browser-with-node-js-and-socket-io/ – Tushar Arora Feb 20 '16 at 20:46
  • Hmm, that seems to do the trick. Apparently, in the link you gave, client was a global variable, whereas in my code client was local to socket.on("login"). I hear that it is bad practice to have a global client, particularly from the guy who wrote the Node.js PostgreSQL library. Here it is: http://stackoverflow.com/questions/8484404/what-is-the-proper-way-to-use-the-node-js-postgresql-module. – goodpoutine Feb 20 '16 at 21:05