11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci// Flags: --expose-gc 31cb0ef41Sopenharmony_ci 41cb0ef41Sopenharmony_ciconst common = require('../../common'); 51cb0ef41Sopenharmony_ciconst assert = require('assert'); 61cb0ef41Sopenharmony_ciconst theError = new Error('Some error'); 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci// The test module throws an error during Init, but in order for its exports to 91cb0ef41Sopenharmony_ci// not be lost, it attaches them to the error's "bindings" property. This way, 101cb0ef41Sopenharmony_ci// we can make sure that exceptions thrown during the module initialization 111cb0ef41Sopenharmony_ci// phase are propagated through require() into JavaScript. 121cb0ef41Sopenharmony_ci// https://github.com/nodejs/node/issues/19437 131cb0ef41Sopenharmony_ciconst test_exception = (function() { 141cb0ef41Sopenharmony_ci let resultingException; 151cb0ef41Sopenharmony_ci try { 161cb0ef41Sopenharmony_ci require(`./build/${common.buildType}/test_exception`); 171cb0ef41Sopenharmony_ci } catch (anException) { 181cb0ef41Sopenharmony_ci resultingException = anException; 191cb0ef41Sopenharmony_ci } 201cb0ef41Sopenharmony_ci assert.strictEqual(resultingException.message, 'Error during Init'); 211cb0ef41Sopenharmony_ci return resultingException.binding; 221cb0ef41Sopenharmony_ci})(); 231cb0ef41Sopenharmony_ci 241cb0ef41Sopenharmony_ci{ 251cb0ef41Sopenharmony_ci const throwTheError = () => { throw theError; }; 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_ci // Test that the native side successfully captures the exception 281cb0ef41Sopenharmony_ci let returnedError = test_exception.returnException(throwTheError); 291cb0ef41Sopenharmony_ci assert.strictEqual(returnedError, theError); 301cb0ef41Sopenharmony_ci 311cb0ef41Sopenharmony_ci // Test that the native side passes the exception through 321cb0ef41Sopenharmony_ci assert.throws( 331cb0ef41Sopenharmony_ci () => { test_exception.allowException(throwTheError); }, 341cb0ef41Sopenharmony_ci (err) => err === theError, 351cb0ef41Sopenharmony_ci ); 361cb0ef41Sopenharmony_ci 371cb0ef41Sopenharmony_ci // Test that the exception thrown above was marked as pending 381cb0ef41Sopenharmony_ci // before it was handled on the JS side 391cb0ef41Sopenharmony_ci const exception_pending = test_exception.wasPending(); 401cb0ef41Sopenharmony_ci assert.strictEqual(exception_pending, true, 411cb0ef41Sopenharmony_ci 'Exception not pending as expected,' + 421cb0ef41Sopenharmony_ci ` .wasPending() returned ${exception_pending}`); 431cb0ef41Sopenharmony_ci 441cb0ef41Sopenharmony_ci // Test that the native side does not capture a non-existing exception 451cb0ef41Sopenharmony_ci returnedError = test_exception.returnException(common.mustCall()); 461cb0ef41Sopenharmony_ci assert.strictEqual(returnedError, undefined, 471cb0ef41Sopenharmony_ci 'Returned error should be undefined when no exception is' + 481cb0ef41Sopenharmony_ci ` thrown, but ${returnedError} was passed`); 491cb0ef41Sopenharmony_ci} 501cb0ef41Sopenharmony_ci 511cb0ef41Sopenharmony_ci 521cb0ef41Sopenharmony_ci{ 531cb0ef41Sopenharmony_ci const throwTheError = class { constructor() { throw theError; } }; 541cb0ef41Sopenharmony_ci 551cb0ef41Sopenharmony_ci // Test that the native side successfully captures the exception 561cb0ef41Sopenharmony_ci let returnedError = test_exception.constructReturnException(throwTheError); 571cb0ef41Sopenharmony_ci assert.strictEqual(returnedError, theError); 581cb0ef41Sopenharmony_ci 591cb0ef41Sopenharmony_ci // Test that the native side passes the exception through 601cb0ef41Sopenharmony_ci assert.throws( 611cb0ef41Sopenharmony_ci () => { test_exception.constructAllowException(throwTheError); }, 621cb0ef41Sopenharmony_ci (err) => err === theError, 631cb0ef41Sopenharmony_ci ); 641cb0ef41Sopenharmony_ci 651cb0ef41Sopenharmony_ci // Test that the exception thrown above was marked as pending 661cb0ef41Sopenharmony_ci // before it was handled on the JS side 671cb0ef41Sopenharmony_ci const exception_pending = test_exception.wasPending(); 681cb0ef41Sopenharmony_ci assert.strictEqual(exception_pending, true, 691cb0ef41Sopenharmony_ci 'Exception not pending as expected,' + 701cb0ef41Sopenharmony_ci ` .wasPending() returned ${exception_pending}`); 711cb0ef41Sopenharmony_ci 721cb0ef41Sopenharmony_ci // Test that the native side does not capture a non-existing exception 731cb0ef41Sopenharmony_ci returnedError = test_exception.constructReturnException(common.mustCall()); 741cb0ef41Sopenharmony_ci assert.strictEqual(returnedError, undefined, 751cb0ef41Sopenharmony_ci 'Returned error should be undefined when no exception is' + 761cb0ef41Sopenharmony_ci ` thrown, but ${returnedError} was passed`); 771cb0ef41Sopenharmony_ci} 781cb0ef41Sopenharmony_ci 791cb0ef41Sopenharmony_ci{ 801cb0ef41Sopenharmony_ci // Test that no exception appears that was not thrown by us 811cb0ef41Sopenharmony_ci let caughtError; 821cb0ef41Sopenharmony_ci try { 831cb0ef41Sopenharmony_ci test_exception.allowException(common.mustCall()); 841cb0ef41Sopenharmony_ci } catch (anError) { 851cb0ef41Sopenharmony_ci caughtError = anError; 861cb0ef41Sopenharmony_ci } 871cb0ef41Sopenharmony_ci assert.strictEqual(caughtError, undefined, 881cb0ef41Sopenharmony_ci 'No exception originated on the native side, but' + 891cb0ef41Sopenharmony_ci ` ${caughtError} was passed`); 901cb0ef41Sopenharmony_ci 911cb0ef41Sopenharmony_ci // Test that the exception state remains clear when no exception is thrown 921cb0ef41Sopenharmony_ci const exception_pending = test_exception.wasPending(); 931cb0ef41Sopenharmony_ci assert.strictEqual(exception_pending, false, 941cb0ef41Sopenharmony_ci 'Exception state did not remain clear as expected,' + 951cb0ef41Sopenharmony_ci ` .wasPending() returned ${exception_pending}`); 961cb0ef41Sopenharmony_ci} 971cb0ef41Sopenharmony_ci 981cb0ef41Sopenharmony_ci{ 991cb0ef41Sopenharmony_ci // Test that no exception appears that was not thrown by us 1001cb0ef41Sopenharmony_ci let caughtError; 1011cb0ef41Sopenharmony_ci try { 1021cb0ef41Sopenharmony_ci test_exception.constructAllowException(common.mustCall()); 1031cb0ef41Sopenharmony_ci } catch (anError) { 1041cb0ef41Sopenharmony_ci caughtError = anError; 1051cb0ef41Sopenharmony_ci } 1061cb0ef41Sopenharmony_ci assert.strictEqual(caughtError, undefined, 1071cb0ef41Sopenharmony_ci 'No exception originated on the native side, but' + 1081cb0ef41Sopenharmony_ci ` ${caughtError} was passed`); 1091cb0ef41Sopenharmony_ci 1101cb0ef41Sopenharmony_ci // Test that the exception state remains clear when no exception is thrown 1111cb0ef41Sopenharmony_ci const exception_pending = test_exception.wasPending(); 1121cb0ef41Sopenharmony_ci assert.strictEqual(exception_pending, false, 1131cb0ef41Sopenharmony_ci 'Exception state did not remain clear as expected,' + 1141cb0ef41Sopenharmony_ci ` .wasPending() returned ${exception_pending}`); 1151cb0ef41Sopenharmony_ci} 116