UNPKG

@webcomponents/custom-elements

Version:
157 lines (139 loc) 5.36 kB
<!DOCTYPE html> <title>Custom Elements: report the exception</title> <script src="../../resources/testharness.js"></script> <script src="../../resources/testharnessreport.js"></script> <script src="resources/custom-elements-helpers.js"></script> <body> <!-- The spec has two places where it says to [report the exception]: 1. In [create an element for a token], step 7. This can occur only when [create an element] is invoked from [create an element for a token] with the synchronous custom elements flag set. The document parser uses this algorithm. 2. In [invoke custom element reactions], step 2.1. There are different code paths when: 1. Author script throws an exception that is rethrown. 2. The user agent throws an exception. This test contains 4 tests for the combination of the above 2x2. [create an element]: https://dom.spec.whatwg.org/#concept-create-element [create an element for a token]: https://html.spec.whatwg.org/multipage/syntax.html#create-an-element-for-the-token [invoke custom element reactions]: https://html.spec.whatwg.org/multipage/scripting.html#invoke-custom-element-reactions [report the exception]: https://html.spec.whatwg.org/multipage/webappapis.html#report-the-exception --> <template id="constructor-throws"> <script> 'use strict'; window.errors = []; // https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-attributes:handler-onerror window.onerror = function (event, source, lineno, colno, error) { errors.push({ event: event, source: source, lineno: lineno, colno: colno, error: error }); return true; // Cancel the error event. }; const rethrowErrorName = 'rethrown'; const rethrowErrorMessage = 'check this is rethrown'; customElements.define('a-a', class extends HTMLElement { constructor() { const error = new Error(rethrowErrorMessage); error.name = rethrowErrorName; throw error; } }); </script> </template> <template id="instantiate"> <a-a></a-a> </template> <script> 'use strict'; const rethrowErrorName = 'rethrown'; const rethrowErrorMessage = 'check this is rethrown'; function assert_not_muted_error_event(error) { assert_not_equals(error, undefined, 'should fire error event'); // Report an error, 6. If script has muted errors, ... // https://html.spec.whatwg.org/multipage/webappapis.html#report-the-error assert_false(error.event === 'Script error.' && error.source === '' && error.lineno === 0 && error.colno === 0 && error.error === null, 'the error should not be muted.'); assert_false(!error.event, 'event (1st arg) should not be null'); assert_false(!error.source, 'source (2nd arg) should not be null'); // The spec doesn't define valid values for lineno/colno. assert_false(!error.error, 'error (5th arg) should not be null'); } function assert_rethrown_error_event(error) { assert_not_muted_error_event(error); assert_equals(error.error.name, rethrowErrorName); assert_equals(error.error.message, rethrowErrorMessage); } const constructor_throws = document.getElementById('constructor-throws').innerHTML; const instantiate = document.getElementById('instantiate').innerHTML; test_with_window((w) => { assert_rethrown_error_event(w.errors[0]); }, 'Document parser invokes the constructor that throws', constructor_throws + instantiate); test_with_window((w) => { w.document.body.innerHTML = instantiate; assert_rethrown_error_event(w.errors[0]); }, 'Upgrade reaction invokes the constructor that throws', constructor_throws); </script> <!-- Test when JavaScript returns without throwing errors, but the result is invalid and thus UA should [report the exception]. --> <template id="constructor-returns-bad-object"> <script> 'use strict'; window.errors = []; // https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-attributes:handler-onerror window.onerror = function (event, source, lineno, colno, error) { errors.push({ event: event, source: source, lineno: lineno, colno: colno, error: error }); return true; // Cancel the error event. }; customElements.define('a-a', class extends HTMLElement { constructor() { super(); return []; // returning objects other than "this" is invalid. } }); </script> </template> <script> const constructor_returns_bad_object = document.getElementById('constructor-returns-bad-object').innerHTML; function assert_type_error_event(error) { assert_not_muted_error_event(error); assert_equals(error.error.name, 'TypeError'); } function assert_invalid_state_dom_error_event(error) { assert_not_muted_error_event(error); assert_equals(error.error.name, 'InvalidStateError'); } test_with_window((w) => { // "create an element" 6.1.3, throw a TypeError. // https://dom.spec.whatwg.org/#concept-create-element assert_type_error_event(w.errors[0]); }, 'Document parser invokes the constructor that returns a bad object', constructor_returns_bad_object + instantiate); test_with_window((w) => { // "upgrade an element" 10, throw an InvalidStateError DOMException. // https://html.spec.whatwg.org/multipage/scripting.html#upgrades w.document.body.innerHTML = instantiate; assert_invalid_state_dom_error_event(w.errors[0]); }, 'Upgrade reaction invokes the constructor that returns a bad object', constructor_returns_bad_object); </script> </body>