feat(router): add support for custom error handlers
This commit is contained in:
parent
93f323cfa2
commit
2fc5c57b31
|
@ -201,6 +201,21 @@ export class RoutesRecognized {
|
|||
export type Event =
|
||||
NavigationStart | NavigationEnd | NavigationCancel | NavigationError | RoutesRecognized;
|
||||
|
||||
/**
|
||||
* Error handler that is invoked when a navigation errors.
|
||||
*
|
||||
* If the handler retuns a value, the navigation promise will be resolved with this value.
|
||||
* If the handler throws an exception, the navigation promise will be rejected with
|
||||
* the exception.
|
||||
*
|
||||
* @stable
|
||||
*/
|
||||
export type ErrorHandler = (error: any) => any;
|
||||
|
||||
function defaultErrorHandler(error: any): any {
|
||||
throw error;
|
||||
}
|
||||
|
||||
/**
|
||||
* The `Router` is responsible for mapping URLs to components.
|
||||
*
|
||||
|
@ -216,6 +231,8 @@ export class Router {
|
|||
private navigationId: number = 0;
|
||||
private configLoader: RouterConfigLoader;
|
||||
|
||||
errorHandler: ErrorHandler = defaultErrorHandler;
|
||||
|
||||
/**
|
||||
* Indicates if at least one navigation happened.
|
||||
*
|
||||
|
@ -533,7 +550,11 @@ export class Router {
|
|||
resolvePromise(false);
|
||||
} else {
|
||||
this.routerEvents.next(new NavigationError(id, this.serializeUrl(url), e));
|
||||
rejectPromise(e);
|
||||
try {
|
||||
resolvePromise(this.errorHandler(e));
|
||||
} catch (ee) {
|
||||
rejectPromise(ee);
|
||||
}
|
||||
}
|
||||
this.currentRouterState = storedState;
|
||||
this.currentUrlTree = storedUrl;
|
||||
|
|
|
@ -13,7 +13,7 @@ import {Route, Routes} from './config';
|
|||
import {RouterLink, RouterLinkWithHref} from './directives/router_link';
|
||||
import {RouterLinkActive} from './directives/router_link_active';
|
||||
import {RouterOutlet} from './directives/router_outlet';
|
||||
import {Router} from './router';
|
||||
import {ErrorHandler, Router} from './router';
|
||||
import {ROUTES} from './router_config_loader';
|
||||
import {RouterOutletMap} from './router_outlet_map';
|
||||
import {ActivatedRoute} from './router_state';
|
||||
|
@ -137,11 +137,18 @@ export function provideRoutes(routes: Routes): any {
|
|||
|
||||
|
||||
/**
|
||||
* Extra options used to configure the router.
|
||||
*
|
||||
* Set `enableTracing` to log router events to the console.
|
||||
* Set 'useHash' to true to enable HashLocationStrategy.
|
||||
* Set `errorHandler` to enable a custom ErrorHandler.
|
||||
*
|
||||
* @stable
|
||||
*/
|
||||
export interface ExtraOptions {
|
||||
enableTracing?: boolean;
|
||||
useHash?: boolean;
|
||||
errorHandler?: ErrorHandler;
|
||||
}
|
||||
|
||||
export function setupRouter(
|
||||
|
@ -156,6 +163,10 @@ export function setupRouter(
|
|||
componentType, urlSerializer, outletMap, location, injector, loader, compiler,
|
||||
flatten(config));
|
||||
|
||||
if (opts.errorHandler) {
|
||||
r.errorHandler = opts.errorHandler;
|
||||
}
|
||||
|
||||
if (opts.enableTracing) {
|
||||
r.events.subscribe(e => {
|
||||
console.group(`Router Event: ${(<any>e.constructor).name}`);
|
||||
|
|
|
@ -427,6 +427,23 @@ describe('Integration', () => {
|
|||
]);
|
||||
})));
|
||||
|
||||
it('should support custom error handlers', fakeAsync(inject([Router], (router: Router) => {
|
||||
router.errorHandler = (error) => 'resolvedValue';
|
||||
const fixture = createRoot(router, RootCmp);
|
||||
|
||||
router.resetConfig([{path: 'user/:name', component: UserCmp}]);
|
||||
|
||||
const recordedEvents: any[] = [];
|
||||
router.events.forEach(e => recordedEvents.push(e));
|
||||
|
||||
let e: any;
|
||||
router.navigateByUrl('/invalid').then(_ => e = _);
|
||||
advance(fixture);
|
||||
expect(e).toEqual('resolvedValue');
|
||||
|
||||
expectEvents(recordedEvents, [[NavigationStart, '/invalid'], [NavigationError, '/invalid']]);
|
||||
})));
|
||||
|
||||
it('should replace state when path is equal to current path',
|
||||
fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
|
||||
const fixture = createRoot(router, RootCmp);
|
||||
|
|
|
@ -72,6 +72,7 @@ export declare type Event = NavigationStart | NavigationEnd | NavigationCancel |
|
|||
/** @stable */
|
||||
export interface ExtraOptions {
|
||||
enableTracing?: boolean;
|
||||
errorHandler?: ErrorHandler;
|
||||
useHash?: boolean;
|
||||
}
|
||||
|
||||
|
@ -168,6 +169,7 @@ export interface Route {
|
|||
/** @stable */
|
||||
export declare class Router {
|
||||
config: Routes;
|
||||
errorHandler: ErrorHandler;
|
||||
events: Observable<Event>;
|
||||
/** @experimental */ navigated: boolean;
|
||||
routerState: RouterState;
|
||||
|
|
Loading…
Reference in New Issue