From e863218ca407c62eb9d7360026c188e29cbf0612 Mon Sep 17 00:00:00 2001 From: thmiceli Date: Thu, 5 Mar 2015 12:59:33 -0800 Subject: [PATCH] Translate C++ exceptions into javascript exceptions --- blpapi.js | 57 +++++++++++++++++++++++++++++++++++++++++++--------- blpapijs.cpp | 36 +++++++++++++++++++++++++-------- package.json | 3 +++ 3 files changed, 78 insertions(+), 18 deletions(-) diff --git a/blpapi.js b/blpapi.js index 50525fa..3f0183f 100644 --- a/blpapi.js +++ b/blpapi.js @@ -2,6 +2,7 @@ var EventEmitter = require('events').EventEmitter; var util = require('util'); var path = require('path'); var blpapi = require(path.join(__dirname, '/build/Release/blpapijs')); +var createCustomError = require('custom-error-generator'); // Note: When support for authorizing multiple identities was added, this // added an optional identity parameter to functions that could be called on @@ -10,6 +11,41 @@ var blpapi = require(path.join(__dirname, '/build/Release/blpapijs')); // with the old number of arguments, they check the last argument and will // accept either a label or identity. +var getError = function () { + var errorTypeNames = [ + 'DuplicateCorrelationIdException', + 'InvalidStateException', + 'InvalidArgumentException', + 'InvalidConversionException', + 'IndexOutOfRangeException', + 'FieldNotFoundException', + 'NotFoundException', + 'UnknownErrorException', + 'UnsupportedOperationException' + ]; + + errorTypeNames.forEach(function(typeName) { + exports[typeName] = createCustomError(typeName, Error); + }); + return function(error) { + var typeName = error.typeName; + if (typeName in exports) { + return new exports[typeName](error.message); + } else { + return error; + } + } +}(); + +var invoke = function(func) { + try { + return func.apply(this, + Array.prototype.slice.call(arguments, 1)); + } catch(err) { + throw getError(err); + } +}; + exports.Session = function(args) { this.session = new blpapi.Session(args); var that = this; @@ -21,27 +57,27 @@ util.inherits(exports.Session, EventEmitter); exports.Session.prototype.start = function() { - return this.session.start(); + return invoke.call(this.session, this.session.start); } exports.Session.prototype.authorize = function(uri, cid) { - return this.session.authorize(uri, cid); + return invoke.call(this.session, this.session.authorize, uri, cid); } exports.Session.prototype.authorizeUser = function(request, cid) { - return this.session.authorizeUser(request, cid); + return invoke.call(this.session, this.session.authorizeUser, request, cid); } exports.Session.prototype.stop = function() { - return this.session.stop(); + return invoke.call(this.session, this.session.stop); } exports.Session.prototype.destroy = function() { - return this.session.destroy(); + return invoke.call(this.session, this.session.destroy); } exports.Session.prototype.openService = function(uri, cid) { - return this.session.openService(uri, cid); + return invoke.call(this.session, this.session.openService, uri, cid); } exports.Session.prototype.subscribe = function(sub, arg2, arg3) { @@ -51,15 +87,15 @@ exports.Session.prototype.subscribe = identity = undefined; label = arg2; } - return this.session.subscribe(sub, identity, label); + return invoke.call(this.session, this.session.subscribe, sub, identity, label); } exports.Session.prototype.resubscribe = function(sub, label) { - return this.session.resubscribe(sub, label); + return invoke.call(this.session, this.session.resubscribe, sub, label); } exports.Session.prototype.unsubscribe = function(sub, label) { - return this.session.unsubscribe(sub, label); + return invoke.call(this.session, this.session.unsubscribe, sub, label); } exports.Session.prototype.request = function(uri, name, request, cid, arg5, arg6) { @@ -69,7 +105,8 @@ exports.Session.prototype.request = identity = undefined; label = arg5; } - return this.session.request(uri, name, request, cid, identity, label); + return invoke.call(this.session, this.session.request, + uri, name, request, cid, identity, label); } // Local variables: diff --git a/blpapijs.cpp b/blpapijs.cpp index 6ce5a68..a914be8 100644 --- a/blpapijs.cpp +++ b/blpapijs.cpp @@ -60,16 +60,36 @@ #endif #define BLPAPI_EXCEPTION_TRY try { -#define BLPAPI_EXCEPTION_CATCH \ - } catch (blpapi::Exception& e) { \ - NoRetThrowException(Exception::Error( \ - NEW_STRING(e.description().c_str()))); \ + +#define BLPAPI_EXCEPTION_NEW(type) \ + Local err = Exception::Error(NEW_STRING(e.description().c_str()))->ToObject(); \ + err->Set(NEW_STRING("typeName"), NEW_STRING(#type)); + +#define BLPAPI_EXCEPTION_THROW(prefix, type) \ + BLPAPI_EXCEPTION_NEW(type) \ + prefix##RetThrowException(err); + +#define BLPAPI_EXCEPTION_CATCH_BLOCK(prefix, type) \ + } catch (const blpapi::type& e) { \ + BLPAPI_EXCEPTION_THROW(prefix, type) + +#define BLPAPI_EXCEPTION_IMPL(prefix) \ + BLPAPI_EXCEPTION_CATCH_BLOCK(prefix, DuplicateCorrelationIdException) \ + BLPAPI_EXCEPTION_CATCH_BLOCK(prefix, InvalidStateException) \ + BLPAPI_EXCEPTION_CATCH_BLOCK(prefix, InvalidArgumentException) \ + BLPAPI_EXCEPTION_CATCH_BLOCK(prefix, InvalidConversionException) \ + BLPAPI_EXCEPTION_CATCH_BLOCK(prefix, IndexOutOfRangeException) \ + BLPAPI_EXCEPTION_CATCH_BLOCK(prefix, FieldNotFoundException) \ + BLPAPI_EXCEPTION_CATCH_BLOCK(prefix, NotFoundException) \ + BLPAPI_EXCEPTION_CATCH_BLOCK(prefix, UnknownErrorException) \ + BLPAPI_EXCEPTION_CATCH_BLOCK(prefix, UnsupportedOperationException) \ } + + +#define BLPAPI_EXCEPTION_CATCH \ + BLPAPI_EXCEPTION_IMPL(No) #define BLPAPI_EXCEPTION_CATCH_RETURN \ - } catch (blpapi::Exception& e) { \ - RetThrowException(Exception::Error( \ - NEW_STRING(e.description().c_str()))); \ - } + BLPAPI_EXCEPTION_IMPL() using namespace node; using namespace v8; diff --git a/package.json b/package.json index c729eaa..baf0625 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,9 @@ "scripts": { "install": "node-gyp configure build" }, + "dependencies": { + "custom-error-generator": ">=7.0.0" + }, "repository": { "type": "git", "url": "https://github.com/bloomberg/blpapi-node.git"