Skip to content
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

Module script error handling is not quite right #2567

Closed
domenic opened this issue Apr 20, 2017 · 0 comments
Closed

Module script error handling is not quite right #2567

domenic opened this issue Apr 20, 2017 · 0 comments

Comments

@domenic
Copy link
Member

domenic commented Apr 20, 2017

@GeorgNeis helped walk me through several error cases:

  1. parsing fails
  2. parsing of dependency fails
  3. instantiation fails
  4. evaluation could fail
  5. in the map, but mapping to null
  6. in the map, but in state "errored"

There are two possible error behaviors, sending to window.onerror and sending to scriptEl.onerror. The intent is that errors "fetching" the script (or its dependencies) go to scriptEl.onerror, while errors "running" the script (or its dependencies) go to window.onerror. Here "fetching" might not involve any actual fetching if the module map already has fetch results, and "running" encompasses parsing, instantiation, and evaluation (and again might not actually do any of those things if the module map already has a result).

The current spec at the very least does not get parsing errors right. It sends them to window.onerror, but then also sends them to scriptEl.onerror, since it results in storing null in the module map.

My tentative suggestion for a fix is that we morph the instantiation state and instantiation error fields into something more general ("state" and "error"?), and if parsing fails, store the error there. Then the module map no longer contains null for parsing failures, but instead an errored script entry. We then remove the "report the exception" inside "create a module script" and let the "report the exception" inside "execute a script block" do the window.onerror work.

I still need to check that this gives the expected behavior for all six cases, but I'm optimistic.

We may also want to, either as part of this or as a separate change, move ParseScript for classic scripts to a different part of the process, to make it more symmetric with module scripts and less confusing. This is not observable since unlike module scripts there is no multi-stage process for fetching/parsing/instantiating/running a classic script, which is why the current inconsistency is not a problem. But it's still confusing for readers.

This impacts several web platform tests.

/cc @whatwg/modules

@domenic domenic self-assigned this Apr 20, 2017
domenic added a commit that referenced this issue Apr 26, 2017
There are several different ways things can go wrong with
<script type=module>. In order from earliest to latest, for a single
module script, they are:

- Fetching failures
- Parsing failures
- Invalid module specifiers
- Instantiation failures
- Evaluation failures

This tweaks the way that these errors interact, to ensure that fetching
failures are treated one way, causing the <script>'s "error" event to
fire, and the other failures are uniformly treated as errors running the
script, causing the global's "error" event to fire.

Fixes #2567.
domenic added a commit that referenced this issue Apr 28, 2017
There are several different ways things can go wrong with
<script type=module>. In order from earliest to latest, for a single
module script, they are:

- Fetching failures
- Parsing failures
- Invalid module specifiers
- Instantiation failures
- Evaluation failures

This tweaks the way that these errors interact, to ensure that fetching
failures are treated one way, causing the <script>'s "error" event to
fire, and the other failures are uniformly treated as errors running the
script, causing the global's "error" event to fire.

Fixes #2567.
domenic added a commit that referenced this issue Apr 28, 2017
There are several different ways things can go wrong with
<script type=module>. In order from earliest to latest, for a single
module script, they are:

- Fetching failures
- Parsing failures
- Invalid module specifiers
- Instantiation failures
- Evaluation failures

This tweaks the way that these errors interact, to ensure that fetching
failures are treated one way, causing the <script>'s "error" event to
fire, and the other failures are uniformly treated as errors running the
script, causing the global's "error" event to fire.

This also makes it clear that when fetching descendant module scripts,
you can bail out early if one of them fails to fetch or has previously
been discovered to be errored.

Fixes #2567.
domenic added a commit that referenced this issue May 1, 2017
There are several different ways things can go wrong with
<script type=module>. In order from earliest to latest, for a single
module script, they are:

- Fetching failures
- Parsing failures
- Invalid module specifiers
- Instantiation failures
- Evaluation failures

This tweaks the way that these errors interact, to ensure that fetching
failures are treated one way, causing the <script>'s "error" event to
fire, and the other failures are uniformly treated as errors running the
script, causing the global's "error" event to fire.

This also makes it clear that when fetching descendant module scripts,
you can bail out early if one of them fails to fetch or has previously
been discovered to be errored.

Fixes #2567.
domenic added a commit that referenced this issue May 3, 2017
There are several different ways things can go wrong with
<script type=module>. In order from earliest to latest, for a single
module script, they are:

- Fetching failures
- Parsing failures
- Invalid module specifiers
- Instantiation failures
- Evaluation failures

This tweaks the way that these errors interact, to ensure that fetching
failures are treated one way, causing the <script>'s "error" event to
fire, and the other failures are uniformly treated as errors running the
script, causing the global's "error" event to fire.

This also makes it clear that when fetching descendant module scripts,
you can bail out early if one of them fails to fetch or has previously
been discovered to be errored.

Evaluation failures are particularly tricky for dependencies, as usually
ModuleEvaluation() is a no-op if it has happened previously
(either successfully or not). This is discussed in more depth in
tc39/ecma262#862. To work around this, we need
to store the evaluation error, if one occurs, similar to what we already
do for instantiation errors.

Fixes #2567.
domenic added a commit that referenced this issue May 12, 2017
There are several different ways things can go wrong with
<script type=module>. In order from earliest to latest, for a single
module script, they are:

- Fetching failures
- Parsing failures
- Invalid module specifiers
- Instantiation failures
- Evaluation failures

This tweaks the way that these errors interact, to ensure that fetching
failures are treated one way, causing the <script>'s "error" event to
fire, and the other failures are uniformly treated as errors running the
script, causing the global's "error" event to fire.

This also makes it clear that when fetching descendant module scripts,
you can bail out early if one of them fails to fetch or has previously
been discovered to be errored.

Evaluation failures are particularly tricky for dependencies, as usually
ModuleEvaluation() is a no-op if it has happened previously
(either successfully or not). This is discussed in more depth in
tc39/ecma262#862. To work around this, we need
to store the evaluation error, if one occurs, similar to what we already
do for instantiation errors.

Fixes #2567.

However, there are still problems with this setup, which may need
further infrastructure changes; see:

- #2595 (comment)
- #2629
- #2630

But for now the improvement given by this commit is enough to merge it.
alice pushed a commit to alice/html that referenced this issue Jan 8, 2019
There are several different ways things can go wrong with
<script type=module>. In order from earliest to latest, for a single
module script, they are:

- Fetching failures
- Parsing failures
- Invalid module specifiers
- Instantiation failures
- Evaluation failures

This tweaks the way that these errors interact, to ensure that fetching
failures are treated one way, causing the <script>'s "error" event to
fire, and the other failures are uniformly treated as errors running the
script, causing the global's "error" event to fire.

This also makes it clear that when fetching descendant module scripts,
you can bail out early if one of them fails to fetch or has previously
been discovered to be errored.

Evaluation failures are particularly tricky for dependencies, as usually
ModuleEvaluation() is a no-op if it has happened previously
(either successfully or not). This is discussed in more depth in
tc39/ecma262#862. To work around this, we need
to store the evaluation error, if one occurs, similar to what we already
do for instantiation errors.

Fixes whatwg#2567.

However, there are still problems with this setup, which may need
further infrastructure changes; see:

- whatwg#2595 (comment)
- whatwg#2629
- whatwg#2630

But for now the improvement given by this commit is enough to merge it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

1 participant