Skip to content
Permalink
Browse files

fix(service-worker): avoid uncaught rejection warning when registrati…

…on 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
  • Loading branch information...
H--o-l authored and mhevery committed Jun 4, 2019
1 parent 9aeef0a commit 08c38a1f99e7e1c61f9191b6eab255b21a6c19bd
Showing with 16 additions and 4 deletions.
  1. +4 −3 packages/service-worker/src/module.ts
  2. +12 −1 packages/service-worker/test/module_spec.ts
@@ -115,10 +115,11 @@ export function ngswAppInitializer(
}
}

// Don't return anything to avoid blocking the application until the SW is registered or
// causing a crash if the SW registration fails.
// Don't return anything to avoid blocking the application until the SW is registered.
// Catch and log the error if SW registration fails to avoid uncaught rejection warning.
readyToRegister$.pipe(take(1)).subscribe(
() => navigator.serviceWorker.register(script, {scope: options.scope}));
() => navigator.serviceWorker.register(script, {scope: options.scope})
.catch(err => console.error('Service worker registration failed with:', err)));
};
return initializer;
}
@@ -28,7 +28,9 @@ describe('ServiceWorkerModule', () => {
return appRef.isStable.pipe(filter(Boolean), take(1)).toPromise();
};

beforeEach(() => swRegisterSpy = spyOn(navigator.serviceWorker, 'register'));
beforeEach(
() => swRegisterSpy =
spyOn(navigator.serviceWorker, 'register').and.returnValue(Promise.resolve()));

describe('register()', () => {
const configTestBed = async(opts: SwRegistrationOptions) => {
@@ -67,6 +69,15 @@ describe('ServiceWorkerModule', () => {
expect(TestBed.get(SwUpdate).isEnabled).toBe(true);
expect(swRegisterSpy).toHaveBeenCalledWith('sw.js', {scope: undefined});
});

it('catches and a logs registration errors', async() => {
const consoleErrorSpy = spyOn(console, 'error');
swRegisterSpy.and.returnValue(Promise.reject('no reason'));

await configTestBed({enabled: true, scope: 'foo'});
expect(consoleErrorSpy)
.toHaveBeenCalledWith('Service worker registration failed with:', 'no reason');
});
});

describe('SwRegistrationOptions', () => {

0 comments on commit 08c38a1

Please sign in to comment.
You can’t perform that action at this time.