fix(service-worker): handle error with ErrorHandler (#39990)

Errors thrown by calling serviceWorker.register() are now passed to the global ErrorHandler.

Fixes #39913

PR Close #39990
This commit is contained in:
Christoph Guttandin 2020-12-05 17:37:03 +01:00 committed by Misko Hevery
parent 6dc43a475b
commit 74e42cf7d5
2 changed files with 14 additions and 9 deletions

View File

@ -7,7 +7,7 @@
*/ */
import {isPlatformBrowser} from '@angular/common'; import {isPlatformBrowser} from '@angular/common';
import {APP_INITIALIZER, ApplicationRef, InjectionToken, Injector, ModuleWithProviders, NgModule, NgZone, PLATFORM_ID} from '@angular/core'; import {APP_INITIALIZER, ApplicationRef, ErrorHandler, InjectionToken, Injector, ModuleWithProviders, NgModule, NgZone, PLATFORM_ID} from '@angular/core';
import {merge, Observable, of} from 'rxjs'; import {merge, Observable, of} from 'rxjs';
import {delay, filter, take} from 'rxjs/operators'; import {delay, filter, take} from 'rxjs/operators';
@ -128,9 +128,10 @@ export function ngswAppInitializer(
const ngZone = injector.get(NgZone); const ngZone = injector.get(NgZone);
ngZone.runOutsideAngular( ngZone.runOutsideAngular(
() => readyToRegister$.pipe(take(1)).subscribe( () => readyToRegister$.pipe(take(1)).subscribe(
() => () => navigator.serviceWorker.register(script, {scope: options.scope}).catch(err => {
navigator.serviceWorker.register(script, {scope: options.scope}) const errorHandler = injector.get(ErrorHandler);
.catch(err => console.error('Service worker registration failed with:', err)))); errorHandler.handleError(err);
})));
}; };
return initializer; return initializer;
} }

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {ApplicationRef, PLATFORM_ID} from '@angular/core'; import {ApplicationRef, ErrorHandler, PLATFORM_ID} from '@angular/core';
import {fakeAsync, flushMicrotasks, TestBed, tick} from '@angular/core/testing'; import {fakeAsync, flushMicrotasks, TestBed, tick} from '@angular/core/testing';
import {Subject} from 'rxjs'; import {Subject} from 'rxjs';
import {filter, take} from 'rxjs/operators'; import {filter, take} from 'rxjs/operators';
@ -21,6 +21,7 @@ describe('ServiceWorkerModule', () => {
return; return;
} }
let errorHandlerSpy: jasmine.Spy;
let swRegisterSpy: jasmine.Spy; let swRegisterSpy: jasmine.Spy;
const untilStable = () => { const untilStable = () => {
@ -34,9 +35,14 @@ describe('ServiceWorkerModule', () => {
describe('register()', () => { describe('register()', () => {
const configTestBed = async (opts: SwRegistrationOptions) => { const configTestBed = async (opts: SwRegistrationOptions) => {
const errorHandler = {handleError: () => {}};
errorHandlerSpy = spyOn(errorHandler, 'handleError');
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ServiceWorkerModule.register('sw.js', opts)], imports: [ServiceWorkerModule.register('sw.js', opts)],
providers: [{provide: PLATFORM_ID, useValue: 'browser'}], providers: [
{provide: ErrorHandler, useValue: errorHandler},
{provide: PLATFORM_ID, useValue: 'browser'},
],
}); });
await untilStable(); await untilStable();
@ -71,12 +77,10 @@ describe('ServiceWorkerModule', () => {
}); });
it('catches and a logs registration errors', async () => { it('catches and a logs registration errors', async () => {
const consoleErrorSpy = spyOn(console, 'error');
swRegisterSpy.and.returnValue(Promise.reject('no reason')); swRegisterSpy.and.returnValue(Promise.reject('no reason'));
await configTestBed({enabled: true, scope: 'foo'}); await configTestBed({enabled: true, scope: 'foo'});
expect(consoleErrorSpy) expect(errorHandlerSpy).toHaveBeenCalledWith('no reason');
.toHaveBeenCalledWith('Service worker registration failed with:', 'no reason');
}); });
}); });