Skip to content

Commit 38a8f2b

Browse files
committed
Fix github issue jakesgordon#17 - Don't swallow errors in SM callbacks
Default behavior for `fsm.error` handler is to rethrow original exception (if there is one). Caller can still customize however they see fit.
1 parent b5cf623 commit 38a8f2b

File tree

3 files changed

+24
-4
lines changed

3 files changed

+24
-4
lines changed

state-machine.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
fsm.is = function(state) { return this.current == state; };
6464
fsm.can = function(event) { return !this.transition && (map[event].hasOwnProperty(this.current) || map[event].hasOwnProperty(StateMachine.WILDCARD)); }
6565
fsm.cannot = function(event) { return !this.can(event); };
66-
fsm.error = cfg.error || function(name, from, to, args, error, msg) { throw msg; }; // default behavior when something unexpected happens is to throw an exception, but caller can override this behavior if desired (see github issue #3)
66+
fsm.error = cfg.error || function(name, from, to, args, error, msg, e) { throw e || msg; }; // default behavior when something unexpected happens is to throw an exception, but caller can override this behavior if desired (see github issue #3 and #17)
6767

6868
if (initial && !initial.defer)
6969
fsm[initial.event]();
@@ -80,7 +80,7 @@
8080
return func.apply(fsm, [name, from, to].concat(args));
8181
}
8282
catch(e) {
83-
return fsm.error(name, from, to, args, StateMachine.Error.INVALID_CALLBACK, "an exception occurred in a caller-provided callback function");
83+
return fsm.error(name, from, to, args, StateMachine.Error.INVALID_CALLBACK, "an exception occurred in a caller-provided callback function", e);
8484
}
8585
}
8686
},

state-machine.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/test_basics.js

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ test("inappropriate events", function() {
151151
test("inappropriate event handling can be customized", function() {
152152

153153
var fsm = StateMachine.create({
154-
error: function(e, name, from, to, args, msg) { return msg; }, // return error message instead of throwing an exception
154+
error: function(name, from, to, args, error, msg) { return msg; }, // return error message instead of throwing an exception
155155
initial: 'green',
156156
events: [
157157
{ name: 'warn', from: 'green', to: 'yellow' },
@@ -363,6 +363,26 @@ test("callback arguments are correct", function() {
363363

364364
//-----------------------------------------------------------------------------
365365

366+
test("exceptions in caller-provided callbacks are not swallowed (github issue #17)", function() {
367+
368+
var fsm = StateMachine.create({
369+
initial: 'green',
370+
events: [
371+
{ name: 'warn', from: 'green', to: 'yellow' },
372+
{ name: 'panic', from: 'yellow', to: 'red' },
373+
{ name: 'calm', from: 'red', to: 'yellow' }
374+
],
375+
callbacks: {
376+
onenteryellow: function() { throw 'oops'; }
377+
}});
378+
379+
equals(fsm.current, 'green', "initial state should be green");
380+
381+
raises(fsm.warn.bind(fsm), /oops/);
382+
});
383+
384+
//-----------------------------------------------------------------------------
385+
366386
test("no-op transitions (github issue #5)", function() {
367387

368388
var fsm = StateMachine.create({

0 commit comments

Comments
 (0)