Skip to content

fix(service-worker): avoid uncaught rejection warning when registration fails #30876

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed

Conversation

H--o-l
Copy link
Contributor

@H--o-l H--o-l commented Jun 5, 2019

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • angular.io application / infrastructure changes
  • Other... Please describe:

What is the current behavior?

After using ServiceWorkerModule.register('/ngsw-worker.js'),, if you have an unstable internet connection, navigator.serviceWorker.register('/ngsw-worker.js') call can fail and your application can crash.
I think that the error can't be caught on the user side.

What is the new behavior?

If navigator.serviceWorker.register('/ngsw-worker.js') fail, there is no uncaught error anymore.

Does this PR introduce a breaking change?

  • Yes
  • No (I'm not completely sure)

Other information

N/A

@H--o-l H--o-l requested a review from a team as a code owner June 5, 2019 15:59
@googlebot
Copy link

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please visit https://cla.developers.google.com/ to sign.

Once you've signed (or fixed any issues), please reply here (e.g. I signed it!) and we'll verify it.


What to do if you already signed the CLA

Individual signers
Corporate signers

ℹ️ Googlers: Go here for more info.

@H--o-l
Copy link
Contributor Author

H--o-l commented Jun 5, 2019

I signed it!

@googlebot
Copy link

CLAs look good, thanks!

ℹ️ Googlers: Go here for more info.

@googlebot googlebot added cla: yes and removed cla: no labels Jun 5, 2019
@H--o-l H--o-l force-pushed the fix/do_not_crash_if_serviceWorker_fail branch from 2e8642e to a0ebcf5 Compare June 5, 2019 16:33
readyToRegister$.pipe(take(1)).subscribe(
() => navigator.serviceWorker.register(script, {scope: options.scope}));
() => navigator.serviceWorker.register(script, {scope: options.scope}).catch(() => {}));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it is a good idea to swallow that error. If the SW fails to register (for whatever reason), the developer should know.
If you want to avoid that the uncaught rejection error, maybe we could explicitly pass it to console.error() inside the catch()? WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @gkalpak, thanks for the feedback.
It's a good idea, here is the diff I just push in my commit:

--- a/packages/service-worker/src/module.ts
+++ b/packages/service-worker/src/module.ts
@@ -118,7 +118,9 @@ export function ngswAppInitializer(
     // Don't return anything to avoid blocking the application until the SW is registered.
     // Catch and ignore the error if SW registration fails.
     readyToRegister$.pipe(take(1)).subscribe(
-        () => navigator.serviceWorker.register(script, {scope: options.scope}).catch(() => {}));
+        () =>
+            navigator.serviceWorker.register(script, {scope: options.scope})
+                .catch(err => console.error('NGSW - service worker register failed with: ', err)));

PS: Would you be able to help me fixing the CI tests ?
If you think this fix is a good idea of course.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The failing tests on CI are due to the fact that we are mocking serviceWorker.register() here, but not returning a promise (which was not necessary before). You need to change the above line to something like:

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

@gkalpak gkalpak added area: service-worker Issues related to the @angular/service-worker package state: WIP target: patch This PR is targeted for the next patch release type: bug/fix labels Jun 5, 2019
@ngbot ngbot bot added this to the needsTriage milestone Jun 5, 2019
@H--o-l H--o-l force-pushed the fix/do_not_crash_if_serviceWorker_fail branch from a0ebcf5 to 589c6ab Compare June 6, 2019 08:36
Copy link
Member

@gkalpak gkalpak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thx, @H--o-l. I left a couple of minor comments, but otherwise lgtm.
I also suggest some changes to the commit message:

  • Change the subject to fix(service-worker): avoid uncaught rejection warning when registration fails
  • Typo: "can failed" --> "can fail"
  • Typo: " a `Uncaught" --> "an `Uncaught"
  • Change the last sentence to describe the new behavior (i.e. logging the error and not ignoring the error).

// 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 ignore the error if SW registration fails.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are not really ignoring it any more. Maybe change to Catch and log the error if SW registration fails to avoid uncaught rejection warning?

() => navigator.serviceWorker.register(script, {scope: options.scope}));
() =>
navigator.serviceWorker.register(script, {scope: options.scope})
.catch(err => console.error('NGSW - service worker register failed with: ', err)));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would change it to just Service worker registration failed with:.

@H--o-l H--o-l force-pushed the fix/do_not_crash_if_serviceWorker_fail branch from 589c6ab to 1d53c41 Compare June 6, 2019 15:22
@H--o-l H--o-l changed the title fix(service-worker): don't crash if registration failed fix(service-worker): avoid uncaught rejection warning when registration fails Jun 6, 2019
@H--o-l
Copy link
Contributor Author

H--o-l commented Jun 6, 2019

@gkalpak, CI looks good, the fix was exactly what you proposed.
I also update the commit and commit message with changes you suggested.

Thanks for your help !

Copy link
Member

@gkalpak gkalpak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Looking at the test fix again, I think it is a good idea to add a test for the new behavior (in module_spec.ts). It could go like this:

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');
});

…on fails

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.
@H--o-l H--o-l force-pushed the fix/do_not_crash_if_serviceWorker_fail branch from 1d53c41 to 31f7764 Compare June 7, 2019 08:57
@H--o-l
Copy link
Contributor Author

H--o-l commented Jun 7, 2019

Hey @gkalpak, thanks for the idea, and the test I should have wrote myself from the beginning.
I add it to the commit, inside the describe('register()', () => { test section.
CI looks to like it 💪

Copy link
Member

@gkalpak gkalpak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great job! Thx, @H--o-l 👍

@gkalpak gkalpak added action: merge The PR is ready for merge by the caretaker and removed state: WIP labels Jun 7, 2019
@mhevery mhevery closed this in 81c2a94 Jun 7, 2019
mhevery pushed a commit that referenced this pull request Jun 7, 2019
…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
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 15, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker area: service-worker Issues related to the @angular/service-worker package cla: yes target: patch This PR is targeted for the next patch release type: bug/fix
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy