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

Onerror Callback Support for Errors Fetching External Import Map #2324

Merged
merged 4 commits into from
Apr 28, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
19 changes: 19 additions & 0 deletions docs/import-maps.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,25 @@ Any existing mappings are replaced, although in future this may be an error.

Previous versions of the import maps spec had support for multiple import maps in a single web page ([explanation](https://github.com/WICG/import-maps/issues/199)). SystemJS added support for multiple import maps during that time and has decided to keep support for multiple import maps as an experimental feature ([discussion](https://github.com/systemjs/systemjs/issues/2095)). Note that the Chrome implementation of import maps does not yet allow for multiple maps, and use of multiple import maps within SystemJS should be considered experimental and subject to change.

### Handling Import Map Errors

For handling errors when fetching external import maps (specifically for [SystemJS Warning #W4](https://github.com/systemjs/systemjs/blob/master/docs/errors.md#w4)), we can use the `onerror` attribute in the `<script type="systemjs-importmap">` tag.

In the `onerror` attribute, specify a script to execute when there is an error.

```html
<script type="systemjs-importmap" onerror="handleError()" src="unable-to-reach/importmap.json"></script>

<script type="text/javascript">
function handleError() {
// Put error handling/retry logic here.
}
</script>

<!-- Can also have inline definition for error handling script -->
<script type="systemjs-importmap" onerror='console.log("Running onerror script")' src="unable-to-reach/importmap.json"></script>
```

#### Spec and Implementation Feedback

Part of the benefit of giving users a working version of an early spec is being able to get real user feedback on the [import maps specification](https://github.com/wicg/import-maps/blob/master/spec.md).
Expand Down
8 changes: 8 additions & 0 deletions src/features/import-maps.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ function processScripts () {
}).catch(function (err) {
err.message = errMsg('W4', process.env.SYSTEM_PRODUCTION ? script.src : 'Error fetching systemjs-import map ' + script.src) + '\n' + err.message;
console.warn(err);
if (typeof script.onerror === 'function') {
try {
script.onerror();
} catch(callbackErr) {
callbackErr.message = 'Error during onerror script for systemjs-importmap: ' + script.src + '\n' + callbackErr.message;
Copy link
Member

Choose a reason for hiding this comment

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

This error should be obtainable from the stack anyway, so let's remove this try-catch wrapper rather. Or did you specifically find the stack didn't have the information needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The stack has the required info, I will remove the try-catch, thanks for the quick review 👍

console.error(callbackErr);
}
}
return '{}';
}) : script.innerHTML;
importMapPromise = importMapPromise.then(function () {
Expand Down
7 changes: 7 additions & 0 deletions test/test.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@

<script type="systemjs-importmap" src="https://hostname.invalid/importmap.json"></script>
<script type="systemjs-importmap" src="fixtures/browser/importmap-invalid.json"></script>
<script type="systemjs-importmap" onerror="retryImportMap()" src="fixtures/browser/importmap-invalid.json"></script>
<script type="systemjs-importmap" onerror="callbackDNE()" src="fixtures/browser/importmap-invalid.json"></script>
<script type="text/javascript">
function retryImportMap() {
document.write('<scr'+'ipt type="systemjs-importmap" src="fixtures/browser/importmap-invalid.json"></sc'+'ript>');
}
</script>
<script type="systemjs-importmap" src="fixtures/browser/importmap.json" integrity="sha384-+t/f9i0vQYwxmcczlIpgCCTQz2mA1sMGYGErJ4fZb/Lcx/yYrFSiedO0XpSIX8oX"></script>
<script type="systemjs-module" src="/test/fixtures/browser/systemjs-module-early.js"></script>
<script src="../dist/system.js"></script>
Expand Down