Skip to content

Commit

Permalink
feat(Transition): expose the transition rejection reason as `Transiti…
Browse files Browse the repository at this point in the history
…on.error()`

Closes #2866
  • Loading branch information
christopherthielen committed Aug 31, 2016
1 parent 92c6388 commit 7a9e383
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 4 deletions.
16 changes: 12 additions & 4 deletions src/transition/transition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ export class Transition implements IHookRegistry {

/** @hidden */
private _deferred = services.$q.defer();
/** @hidden */
private _error: any;
/**
* This promise is resolved or rejected based on the outcome of the Transition.
*
Expand Down Expand Up @@ -156,7 +158,7 @@ export class Transition implements IHookRegistry {
/**
* Determines whether two transitions are equivalent.
*/
is(compare: (Transition|{to: any, from: any})): boolean {
is(compare: (Transition|{to?: any, from?: any})): boolean {
if (compare instanceof Transition) {
// TODO: Also compare parameters
return this.is({ to: compare.$to().name, from: compare.$from().name });
Expand Down Expand Up @@ -474,6 +476,7 @@ export class Transition implements IHookRegistry {
trace.traceError(reason, this);
this.success = false;
this._deferred.reject(reason);
this._error = reason;
runSynchronousHooks(hookBuilder.getOnErrorHooks(), true);
};

Expand All @@ -499,13 +502,16 @@ export class Transition implements IHookRegistry {
* @returns true if the Transition is valid
*/
valid() {
return !this.error();
return !this.error() || this.success !== undefined;
}

/**
* The reason the Transition is invalid
* The Transition error reason.
*
* If the transition is invalid (and could not be run), returns the reason the transition is invalid.
* If the transition was valid and ran, but was not successful, returns the reason the transition failed.
*
* @returns an error message explaining why the transition is invalid
* @returns an error message explaining why the transition is invalid, or the reason the transition failed.
*/
error() {
let state: State = this.$to();
Expand All @@ -514,6 +520,8 @@ export class Transition implements IHookRegistry {
return `Cannot transition to abstract state '${state.name}'`;
if (!Param.validates(state.parameters(), this.params()))
return `Param values not valid for state '${state.name}'`;
if (this.success === false)
return this._error;
}

/**
Expand Down
13 changes: 13 additions & 0 deletions test/core/transitionSpec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,19 @@ describe('transition', function () {
}));
});

// Test for #2866
it('should have access to the failure reason in transition.error().', ((done) => {
let error = new Error("oops!");
let transError;
$transitions.onEnter({ from: "A", entering: "C" }, function() { throw error; });
$transitions.onError({ }, function(trans) { transError = trans.error(); });

Promise.resolve()
.then(goFail("A", "D"))
.then(() => expect(transError).toBe(error))
.then(done);
}));

it("return value of 'false' should reject the transition with ABORT status", ((done) => {
var states = [], rejection, transition = makeTransition("", "D");
$transitions.onEnter({ entering: "*" }, function(trans, state) { states.push(state); });
Expand Down

0 comments on commit 7a9e383

Please sign in to comment.