3

I am specifically interested in how this nodeJS wrapper for quickfix node-quickfix handles failures on sending FIX messages out. The function signature in question seems to be:

function send([Object], callback fn)

This can be seen in the example given here.

Under the hood, node-quickfix takes advantage of NodeJS nan to bind to C++ code. The underlying quickfix package is C++. What I'm curious about is how an error in this send function, say from a network disconnect, is propagated to JS code. In node-quickfix's FIXSession class it overwrites nan's HandleOKCallback (but not its HandleErrorCallback):

void HandleOKCallback () {
    Nan::HandleScope scope;

    v8::Local<v8::Function> fn = callback->GetFunction();
    if(!(fn->IsUndefined() || fn->IsNull())) {
        Local<Value> argv[] = { Nan::Null() };
        callback->Call(1, argv);
    }
};

The definition of nan's default HandleOKCallback and HandleErrorCallback are here. It seems like the FIXInitiator does have an error callback, but I do not know how it is propagated or accessed in javascript/NodeJS for that matter.

EDIT1: I've added a github issue with what I suspect is the issue but I do not know if it is correct, or what the solution is. There is some additional information with my analysis in the github issue.

EDIT2: Added suggested changes to node-quickfix: FixSendWorker.cpp Execute():

void FixSendWorker::Execute () {
  try {
    FIX::Session::sendToTarget(*message);
  } catch(FIX::SessionNotFound& e) {
    this->SetErrorMessage("Failed to send FIX Message");
    std::cout << "*** Session not found!" << std::endl;
  }
}

Code Snippets I used inside my initiator:

console.log('sleeping for 5 seconds');
sleep(5000)
console.log('done sleeping');
this.send(req, (err) => {
    console.log(`ERROR: ${err}`);
});

Definition of sleep:

function sleep(miliseconds) {
   var currentTime = new Date().getTime();
   while (currentTime + miliseconds >= new Date().getTime()) {
   }
}
ajoseps
  • 1,871
  • 1
  • 16
  • 29

1 Answers1

2

I checked the nan Execute function in node-quickfix and it is catching a specific exception and not propagating it:

void FixSendWorker::Execute () {
    try {
        FIX::Session::sendToTarget(*message);
    } catch(FIX::SessionNotFound& e) {
        std::cout << "*** Session not found!" << std::endl;
    }
}

In order to make nan invoke the HandleErrorCallback you should call the SetErrorMessage() function in the catch block of the Execute function. That will cause the error callback on the nodejs side to be called with the error message passed to SetErrorMessage.

I used this post for a source: https://medium.com/@muehler.v/tutorial-to-native-node-js-df4118efb678

maschaub
  • 752
  • 4
  • 10
  • I added the `SetErrorMessage()` to the catch block and tried testing out the fix by logging into the FIX session and then disconnecting right before sending. The error value passed into the callback was still `null`. – ajoseps Aug 13 '19 at 06:06
  • Can you update your answer with the code you tried please? – maschaub Aug 13 '19 at 06:10
  • I'll accept your answer though. I tested out the change in the successful path of execution and it does indeed return an Error object. It seems like the underlying quickfix either does not throw an exception when it fails to send or does not return false. I would need to look into it more. Thank you for the help. – ajoseps Aug 13 '19 at 06:38