diff --git a/.changeset/link-loading-errors.md b/.changeset/link-loading-errors.md new file mode 100644 index 0000000..7cdf484 --- /dev/null +++ b/.changeset/link-loading-errors.md @@ -0,0 +1,8 @@ +--- +"html-include-element": patch +--- + +When included HTML files are loaded, their subresources (defined with `` +elements) are loaded as well. If one of those `` elements fails to load, +`` will now gracefully fail, logging the failed url and +continuing to load the rest of the HTML file. diff --git a/html-include-element.js b/html-include-element.js index d13bb58..c804d3d 100644 --- a/html-include-element.js +++ b/html-include-element.js @@ -30,7 +30,7 @@ async function linkLoaded(link) { else if (isLinkAlreadyLoaded(link)) resolve(link.sheet); else { link.addEventListener('load', () => resolve(link.sheet), { once: true }); - link.addEventListener('error', reject, { once: true }); + link.addEventListener('error', () => reject({ link }), { once: true }); } }); } @@ -139,7 +139,14 @@ export class HTMLIncludeElement extends HTMLElement { // If we're not using shadow DOM, then the consuming root // is responsible to load its own resources if (!this.noShadow) { - await Promise.all([...this.shadowRoot.querySelectorAll('link')].map(linkLoaded)); + const results = await Promise.allSettled([...this.shadowRoot.querySelectorAll('link')].map(linkLoaded)); + for (const result of results) { + if (result.status === 'rejected') { + const { link } = result.reason; + const message = `Could not load ${link.href}`; + console.error(message); + } + } } this.dispatchEvent(new Event('load')); diff --git a/package-lock.json b/package-lock.json index 5c8b607..c7165ca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,8 @@ "license": "Apache-2.0", "devDependencies": { "@esm-bundle/chai": "^4.3.4-fix.0", - "@web/test-runner": "^0.13.27" + "@web/test-runner": "^0.13.27", + "hanbi": "^1.0.1" } }, "node_modules/@babel/code-frame": { @@ -1566,6 +1567,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/hanbi": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hanbi/-/hanbi-1.0.1.tgz", + "integrity": "sha512-ygE4dxg+khS7BZBZTVqaaq+X3oCQX6q4Z2LvNzRpPdZLmzbmL7xu6KCdjWoRiRlYfyZN9R+gMztf4MftiCH0Mw==", + "dev": true + }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -4676,6 +4683,12 @@ "slash": "^3.0.0" } }, + "hanbi": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hanbi/-/hanbi-1.0.1.tgz", + "integrity": "sha512-ygE4dxg+khS7BZBZTVqaaq+X3oCQX6q4Z2LvNzRpPdZLmzbmL7xu6KCdjWoRiRlYfyZN9R+gMztf4MftiCH0Mw==", + "dev": true + }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", diff --git a/package.json b/package.json index 106499f..9558fba 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ ], "devDependencies": { "@esm-bundle/chai": "^4.3.4-fix.0", - "@web/test-runner": "^0.13.27" + "@web/test-runner": "^0.13.27", + "hanbi": "^1.0.1" } } diff --git a/test/html-include-element_test.js b/test/html-include-element_test.js index aaff3fb..84b49df 100644 --- a/test/html-include-element_test.js +++ b/test/html-include-element_test.js @@ -1,4 +1,5 @@ import {assert} from '@esm-bundle/chai'; +import {stubMethod, restore} from 'hanbi'; import '../html-include-element.js'; @@ -63,6 +64,18 @@ suite('html-include-element', () => { }); }); + test('gracefully handles link loading errors', async () => { + const stub = stubMethod(console, 'error'); + container.innerHTML = ` + TEST + `; + const include = container.querySelector('html-include'); + await new Promise((res) => include.addEventListener('load', res)); + assert.isNotNull(include.shadowRoot.querySelector('h1')); + assert.isTrue([...stub.calls].some(call => call.args[0]?.match(/^Could not load/))); + restore(); + }); + // TODO: tests for mode & changing src attribute }); diff --git a/test/test-link-errors.html b/test/test-link-errors.html new file mode 100644 index 0000000..b4002e5 --- /dev/null +++ b/test/test-link-errors.html @@ -0,0 +1,4 @@ + + +

TEST

+