Permalink
Browse files

Issue 224 client errors hide away (#318)

* issue-224 Create an error_handler utility function, add error handlers, update docs.

* issue-224

* issue-224, add end to end test cases, add a timeout handler to the test utils, minor corrections during testing.

* issue-224 Create an error_handler utility function, add error handlers, update docs.

* issue-224

* issue-224 add a minor explanation to the documentation and an example too.
  • Loading branch information...
samson84 authored and oberstet committed Oct 26, 2017
1 parent 10797c7 commit 8ad8f0ece7112d9dca82f80240b28042b578474f
View
@@ -205,6 +205,43 @@ Options that control **WebSocket subprotocol handling**:
- `skip_subprotocol_check`: Not yet implemented.
- `skip_subprotocol_announce`: Not yet implemented.
Options that define **Custom error handlers:**
- `on_user_error`: *function* - This error handler is called in the following cases:
- an exception raised in `onopen`, `onclose`, `onchallenge` callbacks,
- an exception raised in the event handler in the subscriber role,
- an error occurred in the invocation handler in the callee role (the handler called in the client, before
the error message is sent back to the Dealer.)
- `on_internal_error`: *function* - This error handler is called in the following cases:
- not able to create a Wamp transport,
- when a protocol violation is occured,
- when no `onchallenge` defined, but a challenge request is received due to authenticate the client,
```javascript
var connection = new autobahn.Connection({
on_user_error: function (error, customErrorMessage) {
// here comes your custom error handling, when a
// something went wrong in a user defined callback.
},
on_internal_error: function (error, customErrorMessage) {
// here comes your custom error handling, when a
// something went wrong in the autobahn core.
}
// ... other options
});
```
> **note**
>
> If no error handler is defined for these functions, an error level consol log will be written.
> **note**
>
> In a case of error handling in the Callee role, when the invocation handler is executed, the error
> is reported on the Callee side (with the custom error handler or an error log), but despite that the
> error is sent back to the Dealer, and the Caller will receive a `runtime.error` wamp message.
Connection Properties
---------------------
View
@@ -148,11 +148,10 @@ Connection.prototype._create_transport = function () {
return transport;
}
} catch (e) {
// ignore
log.warn("could not create WAMP transport '" + transport_factory.type + "': " + e);
var error_message = "could not create WAMP transport '" + transport_factory.type + "': ";
util.handle_error(self._options.on_internal_error, e, error_message);
}
}
log.warn('could not create any WAMP transport');
return null;
};
@@ -192,7 +191,7 @@ Connection.prototype._init_transport_factories = function () {
this._transport_factories.push(transport_factory);
}
} catch (exc) {
console.error(exc);
util.handle_error(self._options.on_internal_error, exc);
}
}
};
@@ -279,7 +278,7 @@ Connection.prototype.open = function () {
try {
self._transport = self._create_transport();
} catch (e) {
console.log(e);
util.handle_error(self._options.on_internal_error, e);
}
if (!self._transport) {
@@ -299,7 +298,7 @@ Connection.prototype.open = function () {
}
// create a new WAMP session using the WebSocket connection as transport
self._session = new session.Session(self._transport, self._defer, self._options.onchallenge);
self._session = new session.Session(self._transport, self._defer, self._options.onchallenge, self._options.on_user_error, self._options.on_internal_error);
self._session_close_reason = null;
self._session_close_message = null;
@@ -322,7 +321,7 @@ Connection.prototype.open = function () {
details.transport = self._transport.info;
self.onopen(self._session, details);
} catch (e) {
log.debug("Exception raised from app code while firing Connection.onopen()", e);
util.handle_error(self._options.on_user_error, e, "Exception raised from app code while firing Connection.onopen()");
}
}
};
@@ -375,7 +374,7 @@ Connection.prototype.open = function () {
// Connection.onclose() allows to cancel any subsequent retry attempt
var stop_retrying = self.onclose(reason, details);
} catch (e) {
log.debug("Exception raised from app code while firing Connection.onclose()", e);
util.handle_error(self._options.on_user_error, e, "Exception raised from app code while firing Connection.onclose()");
}
}
View
@@ -218,7 +218,7 @@ var MSG_TYPE = {
var Session = function (socket, defer, onchallenge) {
var Session = function (socket, defer, onchallenge, on_user_error, on_internal_error) {
var self = this;
@@ -231,6 +231,11 @@ var Session = function (socket, defer, onchallenge) {
// the WAMP authentication challenge handler
self._onchallenge = onchallenge;
// custom error handlers
self._on_user_error = on_user_error;
self._on_internal_error = on_internal_error;
// the WAMP session ID
self._id = null;
@@ -276,8 +281,8 @@ var Session = function (socket, defer, onchallenge) {
self._protocol_violation = function (reason) {
log.warn("failing transport due to protocol violation: " + reason);
self._socket.close(1002, "protocol violation: " + reason);
util.handle_error(self._on_internal_error, Error("failing transport due to protocol violation: " + reason))
};
self._MESSAGE_MAP = {};
@@ -511,7 +516,7 @@ var Session = function (socket, defer, onchallenge) {
try {
sub.handler(args, kwargs, ed, sub);
} catch (e) {
log.debug("Exception raised in event handler", e);
util.handle_error(self._on_user_error, e, "Exception raised in event handler:");
}
}
@@ -763,7 +768,7 @@ var Session = function (socket, defer, onchallenge) {
}
self._send_wamp(progress_msg);
}
};
}
// we want to provide the regitration procedure to the handler and may
// need to get this from the registration object attached to the registration
@@ -830,6 +835,7 @@ var Session = function (socket, defer, onchallenge) {
// send WAMP message
//
self._send_wamp(reply);
util.handle_error(self._on_user_error, err, "Exception raised in invocation handler:");
}
);
@@ -927,15 +933,14 @@ var Session = function (socket, defer, onchallenge) {
self._send_wamp(msg);
},
function (err) {
log.debug("onchallenge() raised:", err);
var msg = [MSG_TYPE.ABORT, {message: "sorry, I cannot authenticate (onchallenge handler raised an exception)"}, "wamp.error.cannot_authenticate"];
self._send_wamp(msg);
self._socket.close(1000);
util.handle_error(self._on_user_error, err, "onchallenge() raised: ");
var msg = [MSG_TYPE.ABORT, {message: "sorry, I cannot authenticate (onchallenge handler raised an exception)"}, "wamp.error.cannot_authenticate"];
self._send_wamp(msg);
self._socket.close(1000);
}
);
} else {
log.debug("received WAMP challenge, but no onchallenge() handler set");
util.handle_error(self._on_internal_error, Error("received WAMP challenge, but no onchallenge() handler set"));
var msg = [MSG_TYPE.ABORT, {message: "sorry, I cannot authenticate (no onchallenge handler set)"}, "wamp.error.cannot_authenticate"];
self._send_wamp(msg);
View
@@ -264,7 +264,23 @@ var defaults = function () {
return base;
};
/**
* If an error handler function is given, it is called with the error instance, otherwise log the error to the console
* with a possible custom error message prefix. The custom message is passed also the error handler.
*
* @param {function} handler - The error handler function.
* @param {object | Error} error - The error instance.
* @param {string} [error_message] - The custom error message, optional.
*/
var handle_error = function(handler, error, error_message) {
if(typeof handler === 'function') {
handler(error, error_message);
} else {
console.error(error_message || 'Unhandled exception raised: ', error);
}
}
exports.handle_error = handle_error;
exports.rand_normal = rand_normal;
exports.assert = assert;
exports.http_post = http_post;
View
@@ -70,3 +70,8 @@ exports.testPubsubEligible = pubsub_eligible.testPubsubEligible;
exports.testPubsubPrefixSub = pubsub_prefix_sub.testPubsubPrefixSub;
exports.testPubsubWildcardSub = pubsub_wildcard_sub.testPubsubWildcardSub;
exports.testPubsubMultipleMatchingSubs = pubsub_multiple_matching_subs.testPubsubMultipleMatchingSubs;
exports.errorHandlingOnOpen = require('./test_error_handling').errorHandlingOnOpen;
exports.errorHandlingOnClose = require('./test_error_handling').errorHandlingOnClose;
exports.errorHandlingOnEvent = require('./test_error_handling').errorHandlingOnEvent;
exports.errorHandlingOnInvocation = require('./test_error_handling').errorHandlingOnInvocation;
Oops, something went wrong.

0 comments on commit 8ad8f0e

Please sign in to comment.