Skip to content

Commit 08c38a1

Browse files
H--o-lmhevery
authored andcommitted
fix(service-worker): avoid uncaught rejection warning when registration fails (#30876)
Service worker API `navigator.serviceWorker.register` can fail in multiple ways. For example, in Chrome, with an unstable network connection you can have the following error: `An unknown error occurred when fetching the script.` In the current state, it creates an `Uncaught (in promise) TypeError:` style of error, which cannot be caught by the user on his own. I think it's better to log the error over raising an error that cannot be caught. PR Close #30876
1 parent 9aeef0a commit 08c38a1

File tree

2 files changed

+16
-4
lines changed

2 files changed

+16
-4
lines changed

packages/service-worker/src/module.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,11 @@ export function ngswAppInitializer(
115115
}
116116
}
117117

118-
// Don't return anything to avoid blocking the application until the SW is registered or
119-
// causing a crash if the SW registration fails.
118+
// Don't return anything to avoid blocking the application until the SW is registered.
119+
// Catch and log the error if SW registration fails to avoid uncaught rejection warning.
120120
readyToRegister$.pipe(take(1)).subscribe(
121-
() => navigator.serviceWorker.register(script, {scope: options.scope}));
121+
() => navigator.serviceWorker.register(script, {scope: options.scope})
122+
.catch(err => console.error('Service worker registration failed with:', err)));
122123
};
123124
return initializer;
124125
}

packages/service-worker/test/module_spec.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ describe('ServiceWorkerModule', () => {
2828
return appRef.isStable.pipe(filter(Boolean), take(1)).toPromise();
2929
};
3030

31-
beforeEach(() => swRegisterSpy = spyOn(navigator.serviceWorker, 'register'));
31+
beforeEach(
32+
() => swRegisterSpy =
33+
spyOn(navigator.serviceWorker, 'register').and.returnValue(Promise.resolve()));
3234

3335
describe('register()', () => {
3436
const configTestBed = async(opts: SwRegistrationOptions) => {
@@ -67,6 +69,15 @@ describe('ServiceWorkerModule', () => {
6769
expect(TestBed.get(SwUpdate).isEnabled).toBe(true);
6870
expect(swRegisterSpy).toHaveBeenCalledWith('sw.js', {scope: undefined});
6971
});
72+
73+
it('catches and a logs registration errors', async() => {
74+
const consoleErrorSpy = spyOn(console, 'error');
75+
swRegisterSpy.and.returnValue(Promise.reject('no reason'));
76+
77+
await configTestBed({enabled: true, scope: 'foo'});
78+
expect(consoleErrorSpy)
79+
.toHaveBeenCalledWith('Service worker registration failed with:', 'no reason');
80+
});
7081
});
7182

7283
describe('SwRegistrationOptions', () => {

0 commit comments

Comments
 (0)