Skip to content

Commit 7a9e383

Browse files
feat(Transition): expose the transition rejection reason as Transition.error()
Closes #2866
1 parent 92c6388 commit 7a9e383

File tree

2 files changed

+25
-4
lines changed

2 files changed

+25
-4
lines changed

src/transition/transition.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ export class Transition implements IHookRegistry {
5858

5959
/** @hidden */
6060
private _deferred = services.$q.defer();
61+
/** @hidden */
62+
private _error: any;
6163
/**
6264
* This promise is resolved or rejected based on the outcome of the Transition.
6365
*
@@ -156,7 +158,7 @@ export class Transition implements IHookRegistry {
156158
/**
157159
* Determines whether two transitions are equivalent.
158160
*/
159-
is(compare: (Transition|{to: any, from: any})): boolean {
161+
is(compare: (Transition|{to?: any, from?: any})): boolean {
160162
if (compare instanceof Transition) {
161163
// TODO: Also compare parameters
162164
return this.is({ to: compare.$to().name, from: compare.$from().name });
@@ -474,6 +476,7 @@ export class Transition implements IHookRegistry {
474476
trace.traceError(reason, this);
475477
this.success = false;
476478
this._deferred.reject(reason);
479+
this._error = reason;
477480
runSynchronousHooks(hookBuilder.getOnErrorHooks(), true);
478481
};
479482

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

505508
/**
506-
* The reason the Transition is invalid
509+
* The Transition error reason.
510+
*
511+
* If the transition is invalid (and could not be run), returns the reason the transition is invalid.
512+
* If the transition was valid and ran, but was not successful, returns the reason the transition failed.
507513
*
508-
* @returns an error message explaining why the transition is invalid
514+
* @returns an error message explaining why the transition is invalid, or the reason the transition failed.
509515
*/
510516
error() {
511517
let state: State = this.$to();
@@ -514,6 +520,8 @@ export class Transition implements IHookRegistry {
514520
return `Cannot transition to abstract state '${state.name}'`;
515521
if (!Param.validates(state.parameters(), this.params()))
516522
return `Param values not valid for state '${state.name}'`;
523+
if (this.success === false)
524+
return this._error;
517525
}
518526

519527
/**

test/core/transitionSpec.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,19 @@ describe('transition', function () {
343343
}));
344344
});
345345

346+
// Test for #2866
347+
it('should have access to the failure reason in transition.error().', ((done) => {
348+
let error = new Error("oops!");
349+
let transError;
350+
$transitions.onEnter({ from: "A", entering: "C" }, function() { throw error; });
351+
$transitions.onError({ }, function(trans) { transError = trans.error(); });
352+
353+
Promise.resolve()
354+
.then(goFail("A", "D"))
355+
.then(() => expect(transError).toBe(error))
356+
.then(done);
357+
}));
358+
346359
it("return value of 'false' should reject the transition with ABORT status", ((done) => {
347360
var states = [], rejection, transition = makeTransition("", "D");
348361
$transitions.onEnter({ entering: "*" }, function(trans, state) { states.push(state); });

0 commit comments

Comments
 (0)