michaelwittig / node-q

Q interfacing with Node.js
MIT License
52 stars 14 forks source link

Errors not returned when using conn.ks #42

Closed wwarby closed 5 years ago

wwarby commented 5 years ago

There doesn't seem to be any way of reaching an error thrown by an asynchronous call using the conn.ks method. I've put together a simple example of what I mean below - if I call a non-existent function I see an error output directly on the running q process and I can capture that error if I call conn.k, but error argument to the conn.ks method is always undefined, and the connection never fires it's 'error' event.

Is this just an intrinsic limitation of asynchronous calls in node-q or am I doing something wrong? Or is this a bug? I want the performance advantages of asynchronous calls to KDB but I can't risk being unaware of errors returned by the server.

nodeq.connect(
  {
    host: 'localhost',
    port: 5004
  },
  (err, conn) => {
    if (err) {
      console.error(err);
    }
    conn.on('error', err => {
      console.error(err); //Never reaches here
    });
    conn.k('nonExistentFunc', (err, result) => {
      if (err) {
        console.error(err); //Works as expected
      }
    });
    conn.ks('nonExistentFunc', err => {
      if (err) {
        console.error(err); //Never reaches here - err is always undefined
      }
    });
  }
);
michaelwittig commented 5 years ago

You are right, err is always undefined in the callback of ks(...). Socket related errors are emitted on the connection itself and can be seen via conn.on('error' ...) as your code also shows.

The reason why ks(...) does not provide you an error from q is that it's fire and forget. q does not send anything back. The library does not hide the error from you.

In plain q:

q)h: hopen 5000
q)h "nonExistentFunc"
'nonExistentFunc
q)(neg h)"nonExistentFunc"

If you are interested in the result (including errors), use k(...) instead.

Or: You can modify the async request handler https://code.kx.com/v2/ref/dotz/#zps-set , catch all errors, adn send them back to the caller via https://code.kx.com/v2/ref/dotz/#zw-handle

wwarby commented 5 years ago

Thanks for the detailed response Michael, its really useful. I'll need to rethink how my program is designed a little because the reason ks(...) is so much more performant in my scenario is that I'm ingesting data in chunks and with k(...) I'm essentially blocking the thread (even though I'm using a callback) in order to get a response before I move to the next chunk. It seems as though async is the better way to go so I might do as you suggest to send the errors back to the node app.