Skip to content

Commit 182fe78

Browse files
atscottthePunderWoman
authored andcommitted
fix(router): Surface parse errors in Router.parseUrl (#64503)
logs error in addition to fallback parse fixes #54937 PR Close #64503
1 parent 4063082 commit 182fe78

File tree

4 files changed

+37
-3
lines changed

4 files changed

+37
-3
lines changed

goldens/public-api/router/errors.api.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ export const enum RuntimeErrorCode {
99
// (undocumented)
1010
EMPTY_PATH_WITH_PARAMS = 4009,
1111
// (undocumented)
12+
ERROR_PARSING_URL = 4018,
13+
// (undocumented)
1214
FOR_ROOT_CALLED_TWICE = 4007,
1315
// (undocumented)
1416
INFINITE_REDIRECT = 4016,

packages/router/src/errors.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,5 @@ export const enum RuntimeErrorCode {
2828
INVALID_ROOT_URL_SEGMENT = 4015,
2929
INFINITE_REDIRECT = 4016,
3030
INVALID_ROUTER_LINK_INPUTS = 4017,
31+
ERROR_PARSING_URL = 4018,
3132
}

packages/router/src/router.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
Type,
1818
untracked,
1919
ɵINTERNAL_APPLICATION_ERROR_HANDLER,
20+
ɵformatRuntimeError as formatRuntimeError,
2021
} from '@angular/core';
2122
import {Observable, Subject, Subscription, SubscriptionLike} from 'rxjs';
2223

@@ -580,7 +581,13 @@ export class Router {
580581
parseUrl(url: string): UrlTree {
581582
try {
582583
return this.urlSerializer.parse(url);
583-
} catch {
584+
} catch (e) {
585+
this.console.warn(
586+
formatRuntimeError(
587+
RuntimeErrorCode.ERROR_PARSING_URL,
588+
ngDevMode && `Error parsing URL ${url}. Falling back to '/' instead. \n` + e,
589+
),
590+
);
584591
return this.urlSerializer.parse('/');
585592
}
586593
}

packages/router/test/router.spec.ts

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*/
88

99
import {Location} from '@angular/common';
10-
import {EnvironmentInjector, inject} from '@angular/core';
10+
import {EnvironmentInjector, inject, ɵConsole as Console} from '@angular/core';
1111
import {TestBed} from '@angular/core/testing';
1212
import {RouterModule} from '../index';
1313
import {of} from 'rxjs';
@@ -20,7 +20,7 @@ import {resolveData as resolveDataOperator} from '../src/operators/resolve_data'
2020
import {Router} from '../src/router';
2121
import {ChildrenOutletContexts} from '../src/router_outlet_context';
2222
import {createEmptyStateSnapshot, RouterStateSnapshot} from '../src/router_state';
23-
import {DefaultUrlSerializer, UrlTree} from '../src/url_tree';
23+
import {DefaultUrlSerializer, UrlSerializer, UrlTree} from '../src/url_tree';
2424
import {getAllRouteGuards} from '../src/utils/preactivation';
2525
import {TreeNode} from '../src/utils/tree';
2626

@@ -108,6 +108,30 @@ describe('Router', () => {
108108
});
109109
});
110110

111+
describe('parseUrl', () => {
112+
beforeEach(() => {
113+
TestBed.configureTestingModule({imports: [RouterModule.forRoot([])]});
114+
});
115+
116+
it('should log a warning and fall back to "/" when parsing fails', () => {
117+
const router: Router = TestBed.inject(Router);
118+
const urlSerializer: UrlSerializer = TestBed.inject(UrlSerializer);
119+
const console: Console = TestBed.inject(Console);
120+
spyOn(urlSerializer, 'parse').and.callFake((url: string) => {
121+
if (url === 'invalid-url') {
122+
throw new Error('test error');
123+
}
124+
// The fallback call should not be mocked
125+
return new DefaultUrlSerializer().parse(url);
126+
});
127+
const spy = spyOn(console, 'warn');
128+
129+
const result = router.parseUrl('invalid-url');
130+
expect(spy.calls.argsFor(0)).toMatch(/Error parsing URL/);
131+
expect(result).toEqual(new DefaultUrlSerializer().parse('/'));
132+
});
133+
});
134+
111135
describe('PreActivation', () => {
112136
const serializer = new DefaultUrlSerializer();
113137
let empty: RouterStateSnapshot;

0 commit comments

Comments
 (0)