Skip to content

Commit

Permalink
feat(rejectFactory): separate transition aborted and transition error…
Browse files Browse the repository at this point in the history
…ed reject types

feat(defaultErrorHandler): print stack traces for rejections too.
  • Loading branch information
christopherthielen committed Jun 30, 2016
1 parent 10734f1 commit 55995fd
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 12 deletions.
10 changes: 5 additions & 5 deletions src/state/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -272,18 +272,18 @@ export class StateProvider {
}

/**
* @ngdoc function
* @name ui.router.state.$stateProvider#onInvalid
* @methodOf ui.router.state.$stateProvider
* Registers an invalid state handler
*
* @description
* Registers a function to be injected and invoked when transitionTo has been called with an invalid
* Registers a function to be injected and invoked when [[StateService.transitionTo]] has been called with an invalid
* state reference parameter
*
* This function can be injected with one some special values:
* - **`$to$`**: TargetState
* - **`$from$`**: TargetState
*
* Note: This API is subject to change.
* Replacement of dependency injection support with some alternative is likely.
*
* @param {function} callback
* The function which will be injected and invoked, when a matching transition is started.
* The function may optionally return a {TargetState} or a Promise for a TargetState. If one
Expand Down
16 changes: 11 additions & 5 deletions src/state/stateService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,21 @@ export class StateService {
get current() { return this.router.globals.current; }
get $current() { return this.router.globals.$current; }

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

/**
* Invokes the onInvalid callbacks, in natural order. Each callback's return value is checked in sequence
* until one of them returns an instance of TargetState. The results of the callbacks are wrapped
* in $q.when(), so the callbacks may return promises.
* Handler for when [[transitionTo]] is called with an invalid state.
*
* Invokes the [[onInvalid]] callbacks, in natural order.
* Each callback's return value is checked in sequence until one of them returns an instance of TargetState.
* The results of the callbacks are wrapped in $q.when(), so the callbacks may return promises.
*
* If a callback returns an TargetState, then it is used as arguments to $state.transitionTo() and
* the result returned.
* If a callback returns an TargetState, then it is used as arguments to $state.transitionTo() and the result returned.
*/
private _handleInvalidTargetState(fromPath: PathNode[], $to$: TargetState) {
let globals = <Globals> this.router.globals;
Expand Down Expand Up @@ -482,6 +484,10 @@ export class StateService {
private _defaultErrorHandler: ((_error) => void) = function $defaultErrorHandler($error$) {
if ($error$ instanceof Error && $error$.stack) {
console.error($error$.stack);
} else if ($error$ instanceof Rejection) {
console.error($error$);
if ($error$.detail && $error$.detail.stack)
console.error($error$.detail.stack);
} else {
console.error($error$);
}
Expand Down
9 changes: 8 additions & 1 deletion src/transition/rejectFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {extend, silentRejection} from "../common/common";
import {stringify} from "../common/strings";

export enum RejectType {
SUPERSEDED = 2, ABORTED = 3, INVALID = 4, IGNORED = 5
SUPERSEDED = 2, ABORTED = 3, INVALID = 4, IGNORED = 5, ERROR = 6
}

export class Rejection {
Expand Down Expand Up @@ -67,4 +67,11 @@ export class Rejection {
let message = "The transition has been aborted.";
return new Rejection(RejectType.ABORTED, message, detail);
}

/** Returns a TransitionRejection due to aborted transition */
static errored(detail?: any) {
// TODO think about how to encapsulate an Error() object
let message = "The transition errored.";
return new Rejection(RejectType.ERROR, message, detail);
}
}
2 changes: 1 addition & 1 deletion src/transition/transitionHook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export class TransitionHook {
results.push(hooks[i].invokeHook());
} catch (exception) {
if (!swallowExceptions) {
return Rejection.aborted(exception).toPromise();
return Rejection.errored(exception).toPromise();
}

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

0 comments on commit 55995fd

Please sign in to comment.