Skip to content

Commit 55995fd

Browse files
feat(rejectFactory): separate transition aborted and transition errored reject types
feat(defaultErrorHandler): print stack traces for rejections too.
1 parent 10734f1 commit 55995fd

File tree

4 files changed

+25
-12
lines changed

4 files changed

+25
-12
lines changed

src/state/state.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -272,18 +272,18 @@ export class StateProvider {
272272
}
273273

274274
/**
275-
* @ngdoc function
276-
* @name ui.router.state.$stateProvider#onInvalid
277-
* @methodOf ui.router.state.$stateProvider
275+
* Registers an invalid state handler
278276
*
279-
* @description
280-
* Registers a function to be injected and invoked when transitionTo has been called with an invalid
277+
* Registers a function to be injected and invoked when [[StateService.transitionTo]] has been called with an invalid
281278
* state reference parameter
282279
*
283280
* This function can be injected with one some special values:
284281
* - **`$to$`**: TargetState
285282
* - **`$from$`**: TargetState
286283
*
284+
* Note: This API is subject to change.
285+
* Replacement of dependency injection support with some alternative is likely.
286+
*
287287
* @param {function} callback
288288
* The function which will be injected and invoked, when a matching transition is started.
289289
* The function may optionally return a {TargetState} or a Promise for a TargetState. If one

src/state/stateService.ts

+11-5
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,21 @@ export class StateService {
3333
get current() { return this.router.globals.current; }
3434
get $current() { return this.router.globals.$current; }
3535

36+
/** @hidden */
3637
constructor(private router: UIRouter) {
3738
let getters = ['current', '$current', 'params', 'transition'];
3839
let boundFns = Object.keys(StateService.prototype).filter(key => getters.indexOf(key) === -1);
3940
bindFunctions(StateService.prototype, this, this, boundFns);
4041
}
4142

4243
/**
43-
* Invokes the onInvalid callbacks, in natural order. Each callback's return value is checked in sequence
44-
* until one of them returns an instance of TargetState. The results of the callbacks are wrapped
45-
* in $q.when(), so the callbacks may return promises.
44+
* Handler for when [[transitionTo]] is called with an invalid state.
45+
*
46+
* Invokes the [[onInvalid]] callbacks, in natural order.
47+
* Each callback's return value is checked in sequence until one of them returns an instance of TargetState.
48+
* The results of the callbacks are wrapped in $q.when(), so the callbacks may return promises.
4649
*
47-
* If a callback returns an TargetState, then it is used as arguments to $state.transitionTo() and
48-
* the result returned.
50+
* If a callback returns an TargetState, then it is used as arguments to $state.transitionTo() and the result returned.
4951
*/
5052
private _handleInvalidTargetState(fromPath: PathNode[], $to$: TargetState) {
5153
let globals = <Globals> this.router.globals;
@@ -482,6 +484,10 @@ export class StateService {
482484
private _defaultErrorHandler: ((_error) => void) = function $defaultErrorHandler($error$) {
483485
if ($error$ instanceof Error && $error$.stack) {
484486
console.error($error$.stack);
487+
} else if ($error$ instanceof Rejection) {
488+
console.error($error$);
489+
if ($error$.detail && $error$.detail.stack)
490+
console.error($error$.detail.stack);
485491
} else {
486492
console.error($error$);
487493
}

src/transition/rejectFactory.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {extend, silentRejection} from "../common/common";
44
import {stringify} from "../common/strings";
55

66
export enum RejectType {
7-
SUPERSEDED = 2, ABORTED = 3, INVALID = 4, IGNORED = 5
7+
SUPERSEDED = 2, ABORTED = 3, INVALID = 4, IGNORED = 5, ERROR = 6
88
}
99

1010
export class Rejection {
@@ -67,4 +67,11 @@ export class Rejection {
6767
let message = "The transition has been aborted.";
6868
return new Rejection(RejectType.ABORTED, message, detail);
6969
}
70+
71+
/** Returns a TransitionRejection due to aborted transition */
72+
static errored(detail?: any) {
73+
// TODO think about how to encapsulate an Error() object
74+
let message = "The transition errored.";
75+
return new Rejection(RejectType.ERROR, message, detail);
76+
}
7077
}

src/transition/transitionHook.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ export class TransitionHook {
9494
results.push(hooks[i].invokeHook());
9595
} catch (exception) {
9696
if (!swallowExceptions) {
97-
return Rejection.aborted(exception).toPromise();
97+
return Rejection.errored(exception).toPromise();
9898
}
9999

100100
console.error("Swallowed exception during synchronous hook handler: " + exception); // TODO: What to do here?

0 commit comments

Comments
 (0)