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

Re-throw evaluation errors on deferred namespace property access #43

Merged
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -342,3 +342,36 @@ function Foo() {

However, this solution doesn't cover deferring the loading of submodules of a lazy graph, and would
not acheive the characteristics we are looking for.

#### Why `import defer *` gives a different namespace object from `import *`?

If a deferred module throws while being evaluated, `ns.foo` will throw the evaluation error:

```js
// module-that-throws1
export let a = 1;
throw new Error("oops");
```
```js
// main1.js
import defer * as ns1 from 'module-that-throws';
try { ns1.a } catch (e) { console.log('caught', e) } // logs "oops"
```

Module namespace objects of modules that are already evaluated do now throw error on
property access:
```js
// module-that-throws2
import * as ns2 from 'module-that-throws';
globalThis.ns2 = ns2;
export let a = 1;
throw new Error("oops");
```
```js
// main2.ja
nicolo-ribaudo marked this conversation as resolved.
Show resolved Hide resolved
import("module-that-throws").finally(() => {
try { ns2.a } catch (e) { console.log('caught', e) } // Doesn't throw
});
```

This is not a problem today, because having access to the namespace object of a module that threw during evaluation is incredibly rare. However, it would be incredibly more common with `import defer` declarations. To guarantee that the behavior of `main1.js` is not affected by module previously loaded, `ns2.foo` must throw even if `module-that-throws` is already evaluated, and thus it cannot be the same namespace object as `import *`.
Loading