11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ci// This test makes sure that when throwing an error from a domain, and then 41cb0ef41Sopenharmony_ci// handling that error in an uncaughtException handler by throwing an error 51cb0ef41Sopenharmony_ci// again, the exit code, signal and error messages are the ones we expect with 61cb0ef41Sopenharmony_ci// and without using --abort-on-uncaught-exception. 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ciconst common = require('../common'); 91cb0ef41Sopenharmony_ciconst assert = require('assert'); 101cb0ef41Sopenharmony_ciconst child_process = require('child_process'); 111cb0ef41Sopenharmony_ciconst domain = require('domain'); 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_ciconst uncaughtExceptionHandlerErrMsg = 'boom from uncaughtException handler'; 141cb0ef41Sopenharmony_ciconst domainErrMsg = 'boom from domain'; 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_ciconst RAN_UNCAUGHT_EXCEPTION_HANDLER_EXIT_CODE = 42; 171cb0ef41Sopenharmony_ci 181cb0ef41Sopenharmony_ciif (process.argv[2] === 'child') { 191cb0ef41Sopenharmony_ci process.on('uncaughtException', common.mustCall(function onUncaught() { 201cb0ef41Sopenharmony_ci if (process.execArgv.includes('--abort-on-uncaught-exception')) { 211cb0ef41Sopenharmony_ci // When passing --abort-on-uncaught-exception to the child process, 221cb0ef41Sopenharmony_ci // we want to make sure that this handler (the process' uncaughtException 231cb0ef41Sopenharmony_ci // event handler) wasn't called. Unfortunately we can't parse the child 241cb0ef41Sopenharmony_ci // process' output to do that, since on Windows the standard error output 251cb0ef41Sopenharmony_ci // is not properly flushed in V8's Isolate::Throw right before the 261cb0ef41Sopenharmony_ci // process aborts due to an uncaught exception, and thus the error 271cb0ef41Sopenharmony_ci // message representing the error that was thrown cannot be read by the 281cb0ef41Sopenharmony_ci // parent process. So instead of parsing the child process' standard 291cb0ef41Sopenharmony_ci // error, the parent process will check that in the case 301cb0ef41Sopenharmony_ci // --abort-on-uncaught-exception was passed, the process did not exit 311cb0ef41Sopenharmony_ci // with exit code RAN_UNCAUGHT_EXCEPTION_HANDLER_EXIT_CODE. 321cb0ef41Sopenharmony_ci process.exit(RAN_UNCAUGHT_EXCEPTION_HANDLER_EXIT_CODE); 331cb0ef41Sopenharmony_ci } else { 341cb0ef41Sopenharmony_ci // On the other hand, when not passing --abort-on-uncaught-exception to 351cb0ef41Sopenharmony_ci // the node process, we want to throw in this event handler to make sure 361cb0ef41Sopenharmony_ci // that the proper error message, exit code and signal are the ones we 371cb0ef41Sopenharmony_ci // expect. 381cb0ef41Sopenharmony_ci throw new Error(uncaughtExceptionHandlerErrMsg); 391cb0ef41Sopenharmony_ci } 401cb0ef41Sopenharmony_ci })); 411cb0ef41Sopenharmony_ci 421cb0ef41Sopenharmony_ci const d = domain.create(); 431cb0ef41Sopenharmony_ci d.run(common.mustCall(function() { 441cb0ef41Sopenharmony_ci throw new Error(domainErrMsg); 451cb0ef41Sopenharmony_ci })); 461cb0ef41Sopenharmony_ci} else { 471cb0ef41Sopenharmony_ci runTestWithoutAbortOnUncaughtException(); 481cb0ef41Sopenharmony_ci runTestWithAbortOnUncaughtException(); 491cb0ef41Sopenharmony_ci} 501cb0ef41Sopenharmony_ci 511cb0ef41Sopenharmony_cifunction runTestWithoutAbortOnUncaughtException() { 521cb0ef41Sopenharmony_ci child_process.exec( 531cb0ef41Sopenharmony_ci createTestCmdLine(), 541cb0ef41Sopenharmony_ci function onTestDone(err, stdout, stderr) { 551cb0ef41Sopenharmony_ci // When _not_ passing --abort-on-uncaught-exception, the process' 561cb0ef41Sopenharmony_ci // uncaughtException handler _must_ be called, and thus the error 571cb0ef41Sopenharmony_ci // message must include only the message of the error thrown from the 581cb0ef41Sopenharmony_ci // process' uncaughtException handler. 591cb0ef41Sopenharmony_ci assert(stderr.includes(uncaughtExceptionHandlerErrMsg), 601cb0ef41Sopenharmony_ci 'stderr output must include proper uncaughtException ' + 611cb0ef41Sopenharmony_ci 'handler\'s error\'s message'); 621cb0ef41Sopenharmony_ci assert(!stderr.includes(domainErrMsg), 631cb0ef41Sopenharmony_ci 'stderr output must not include domain\'s error\'s message'); 641cb0ef41Sopenharmony_ci 651cb0ef41Sopenharmony_ci assert.notStrictEqual(err.code, 0, 661cb0ef41Sopenharmony_ci 'child process should have exited with a ' + 671cb0ef41Sopenharmony_ci 'non-zero exit code, but did not'); 681cb0ef41Sopenharmony_ci } 691cb0ef41Sopenharmony_ci ); 701cb0ef41Sopenharmony_ci} 711cb0ef41Sopenharmony_ci 721cb0ef41Sopenharmony_cifunction runTestWithAbortOnUncaughtException() { 731cb0ef41Sopenharmony_ci child_process.exec(createTestCmdLine({ 741cb0ef41Sopenharmony_ci withAbortOnUncaughtException: true 751cb0ef41Sopenharmony_ci }), function onTestDone(err, stdout, stderr) { 761cb0ef41Sopenharmony_ci assert.notStrictEqual(err.code, RAN_UNCAUGHT_EXCEPTION_HANDLER_EXIT_CODE, 771cb0ef41Sopenharmony_ci 'child process should not have run its ' + 781cb0ef41Sopenharmony_ci 'uncaughtException event handler'); 791cb0ef41Sopenharmony_ci assert(common.nodeProcessAborted(err.code, err.signal), 801cb0ef41Sopenharmony_ci 'process should have aborted, but did not'); 811cb0ef41Sopenharmony_ci }); 821cb0ef41Sopenharmony_ci} 831cb0ef41Sopenharmony_ci 841cb0ef41Sopenharmony_cifunction createTestCmdLine(options) { 851cb0ef41Sopenharmony_ci let testCmd = ''; 861cb0ef41Sopenharmony_ci 871cb0ef41Sopenharmony_ci if (!common.isWindows) { 881cb0ef41Sopenharmony_ci // Do not create core files, as it can take a lot of disk space on 891cb0ef41Sopenharmony_ci // continuous testing and developers' machines 901cb0ef41Sopenharmony_ci testCmd += 'ulimit -c 0 && '; 911cb0ef41Sopenharmony_ci } 921cb0ef41Sopenharmony_ci 931cb0ef41Sopenharmony_ci testCmd += `"${process.argv[0]}"`; 941cb0ef41Sopenharmony_ci 951cb0ef41Sopenharmony_ci if (options && options.withAbortOnUncaughtException) { 961cb0ef41Sopenharmony_ci testCmd += ' --abort-on-uncaught-exception'; 971cb0ef41Sopenharmony_ci } 981cb0ef41Sopenharmony_ci 991cb0ef41Sopenharmony_ci testCmd += ` "${process.argv[1]}" child`; 1001cb0ef41Sopenharmony_ci 1011cb0ef41Sopenharmony_ci return testCmd; 1021cb0ef41Sopenharmony_ci} 103