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()) {
}
}
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