11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ciconst common = require('../common'); 31cb0ef41Sopenharmony_ciconst assert = require('assert'); 41cb0ef41Sopenharmony_ciconst { EventEmitter, captureRejectionSymbol } = require('events'); 51cb0ef41Sopenharmony_ciconst { inherits } = require('util'); 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ci// Inherits from EE without a call to the 81cb0ef41Sopenharmony_ci// parent constructor. 91cb0ef41Sopenharmony_cifunction NoConstructor() { 101cb0ef41Sopenharmony_ci} 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_ci// captureRejections param validation 131cb0ef41Sopenharmony_ci{ 141cb0ef41Sopenharmony_ci [1, [], function() {}, {}, Infinity, Math.PI, 'meow'].forEach((arg) => { 151cb0ef41Sopenharmony_ci assert.throws( 161cb0ef41Sopenharmony_ci () => new EventEmitter({ captureRejections: arg }), 171cb0ef41Sopenharmony_ci { 181cb0ef41Sopenharmony_ci name: 'TypeError', 191cb0ef41Sopenharmony_ci code: 'ERR_INVALID_ARG_TYPE', 201cb0ef41Sopenharmony_ci message: 'The "options.captureRejections" property must be of type boolean.' + 211cb0ef41Sopenharmony_ci common.invalidArgTypeHelper(arg), 221cb0ef41Sopenharmony_ci } 231cb0ef41Sopenharmony_ci ); 241cb0ef41Sopenharmony_ci }); 251cb0ef41Sopenharmony_ci} 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_ciinherits(NoConstructor, EventEmitter); 281cb0ef41Sopenharmony_ci 291cb0ef41Sopenharmony_cifunction captureRejections() { 301cb0ef41Sopenharmony_ci const ee = new EventEmitter({ captureRejections: true }); 311cb0ef41Sopenharmony_ci const _err = new Error('kaboom'); 321cb0ef41Sopenharmony_ci ee.on('something', common.mustCall(async (value) => { 331cb0ef41Sopenharmony_ci throw _err; 341cb0ef41Sopenharmony_ci })); 351cb0ef41Sopenharmony_ci 361cb0ef41Sopenharmony_ci ee.on('error', common.mustCall((err) => { 371cb0ef41Sopenharmony_ci assert.strictEqual(err, _err); 381cb0ef41Sopenharmony_ci process.nextTick(captureRejectionsTwoHandlers); 391cb0ef41Sopenharmony_ci })); 401cb0ef41Sopenharmony_ci 411cb0ef41Sopenharmony_ci ee.emit('something'); 421cb0ef41Sopenharmony_ci} 431cb0ef41Sopenharmony_ci 441cb0ef41Sopenharmony_cifunction captureRejectionsTwoHandlers() { 451cb0ef41Sopenharmony_ci const ee = new EventEmitter({ captureRejections: true }); 461cb0ef41Sopenharmony_ci const _err = new Error('kaboom'); 471cb0ef41Sopenharmony_ci 481cb0ef41Sopenharmony_ci ee.on('something', common.mustCall(async (value) => { 491cb0ef41Sopenharmony_ci throw _err; 501cb0ef41Sopenharmony_ci })); 511cb0ef41Sopenharmony_ci 521cb0ef41Sopenharmony_ci // throw twice 531cb0ef41Sopenharmony_ci ee.on('something', common.mustCall(async (value) => { 541cb0ef41Sopenharmony_ci throw _err; 551cb0ef41Sopenharmony_ci })); 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_ci let count = 0; 581cb0ef41Sopenharmony_ci 591cb0ef41Sopenharmony_ci ee.on('error', common.mustCall((err) => { 601cb0ef41Sopenharmony_ci assert.strictEqual(err, _err); 611cb0ef41Sopenharmony_ci if (++count === 2) { 621cb0ef41Sopenharmony_ci process.nextTick(defaultValue); 631cb0ef41Sopenharmony_ci } 641cb0ef41Sopenharmony_ci }, 2)); 651cb0ef41Sopenharmony_ci 661cb0ef41Sopenharmony_ci ee.emit('something'); 671cb0ef41Sopenharmony_ci} 681cb0ef41Sopenharmony_ci 691cb0ef41Sopenharmony_cifunction defaultValue() { 701cb0ef41Sopenharmony_ci const ee = new EventEmitter(); 711cb0ef41Sopenharmony_ci const _err = new Error('kaboom'); 721cb0ef41Sopenharmony_ci ee.on('something', common.mustCall(async (value) => { 731cb0ef41Sopenharmony_ci throw _err; 741cb0ef41Sopenharmony_ci })); 751cb0ef41Sopenharmony_ci 761cb0ef41Sopenharmony_ci process.removeAllListeners('unhandledRejection'); 771cb0ef41Sopenharmony_ci 781cb0ef41Sopenharmony_ci process.once('unhandledRejection', common.mustCall((err) => { 791cb0ef41Sopenharmony_ci // restore default 801cb0ef41Sopenharmony_ci process.on('unhandledRejection', (err) => { throw err; }); 811cb0ef41Sopenharmony_ci 821cb0ef41Sopenharmony_ci assert.strictEqual(err, _err); 831cb0ef41Sopenharmony_ci process.nextTick(globalSetting); 841cb0ef41Sopenharmony_ci })); 851cb0ef41Sopenharmony_ci 861cb0ef41Sopenharmony_ci ee.emit('something'); 871cb0ef41Sopenharmony_ci} 881cb0ef41Sopenharmony_ci 891cb0ef41Sopenharmony_cifunction globalSetting() { 901cb0ef41Sopenharmony_ci assert.strictEqual(EventEmitter.captureRejections, false); 911cb0ef41Sopenharmony_ci EventEmitter.captureRejections = true; 921cb0ef41Sopenharmony_ci const ee = new EventEmitter(); 931cb0ef41Sopenharmony_ci const _err = new Error('kaboom'); 941cb0ef41Sopenharmony_ci ee.on('something', common.mustCall(async (value) => { 951cb0ef41Sopenharmony_ci throw _err; 961cb0ef41Sopenharmony_ci })); 971cb0ef41Sopenharmony_ci 981cb0ef41Sopenharmony_ci ee.on('error', common.mustCall((err) => { 991cb0ef41Sopenharmony_ci assert.strictEqual(err, _err); 1001cb0ef41Sopenharmony_ci 1011cb0ef41Sopenharmony_ci // restore default 1021cb0ef41Sopenharmony_ci EventEmitter.captureRejections = false; 1031cb0ef41Sopenharmony_ci process.nextTick(configurable); 1041cb0ef41Sopenharmony_ci })); 1051cb0ef41Sopenharmony_ci 1061cb0ef41Sopenharmony_ci ee.emit('something'); 1071cb0ef41Sopenharmony_ci} 1081cb0ef41Sopenharmony_ci 1091cb0ef41Sopenharmony_ci// We need to be able to configure this for streams, as we would 1101cb0ef41Sopenharmony_ci// like to call destroy(err) there. 1111cb0ef41Sopenharmony_cifunction configurable() { 1121cb0ef41Sopenharmony_ci const ee = new EventEmitter({ captureRejections: true }); 1131cb0ef41Sopenharmony_ci const _err = new Error('kaboom'); 1141cb0ef41Sopenharmony_ci ee.on('something', common.mustCall(async (...args) => { 1151cb0ef41Sopenharmony_ci assert.deepStrictEqual(args, [42, 'foobar']); 1161cb0ef41Sopenharmony_ci throw _err; 1171cb0ef41Sopenharmony_ci })); 1181cb0ef41Sopenharmony_ci 1191cb0ef41Sopenharmony_ci assert.strictEqual(captureRejectionSymbol, Symbol.for('nodejs.rejection')); 1201cb0ef41Sopenharmony_ci 1211cb0ef41Sopenharmony_ci ee[captureRejectionSymbol] = common.mustCall((err, type, ...args) => { 1221cb0ef41Sopenharmony_ci assert.strictEqual(err, _err); 1231cb0ef41Sopenharmony_ci assert.strictEqual(type, 'something'); 1241cb0ef41Sopenharmony_ci assert.deepStrictEqual(args, [42, 'foobar']); 1251cb0ef41Sopenharmony_ci process.nextTick(globalSettingNoConstructor); 1261cb0ef41Sopenharmony_ci }); 1271cb0ef41Sopenharmony_ci 1281cb0ef41Sopenharmony_ci ee.emit('something', 42, 'foobar'); 1291cb0ef41Sopenharmony_ci} 1301cb0ef41Sopenharmony_ci 1311cb0ef41Sopenharmony_cifunction globalSettingNoConstructor() { 1321cb0ef41Sopenharmony_ci assert.strictEqual(EventEmitter.captureRejections, false); 1331cb0ef41Sopenharmony_ci EventEmitter.captureRejections = true; 1341cb0ef41Sopenharmony_ci const ee = new NoConstructor(); 1351cb0ef41Sopenharmony_ci const _err = new Error('kaboom'); 1361cb0ef41Sopenharmony_ci ee.on('something', common.mustCall(async (value) => { 1371cb0ef41Sopenharmony_ci throw _err; 1381cb0ef41Sopenharmony_ci })); 1391cb0ef41Sopenharmony_ci 1401cb0ef41Sopenharmony_ci ee.on('error', common.mustCall((err) => { 1411cb0ef41Sopenharmony_ci assert.strictEqual(err, _err); 1421cb0ef41Sopenharmony_ci 1431cb0ef41Sopenharmony_ci // restore default 1441cb0ef41Sopenharmony_ci EventEmitter.captureRejections = false; 1451cb0ef41Sopenharmony_ci process.nextTick(thenable); 1461cb0ef41Sopenharmony_ci })); 1471cb0ef41Sopenharmony_ci 1481cb0ef41Sopenharmony_ci ee.emit('something'); 1491cb0ef41Sopenharmony_ci} 1501cb0ef41Sopenharmony_ci 1511cb0ef41Sopenharmony_cifunction thenable() { 1521cb0ef41Sopenharmony_ci const ee = new EventEmitter({ captureRejections: true }); 1531cb0ef41Sopenharmony_ci const _err = new Error('kaboom'); 1541cb0ef41Sopenharmony_ci ee.on('something', common.mustCall((value) => { 1551cb0ef41Sopenharmony_ci const obj = {}; 1561cb0ef41Sopenharmony_ci 1571cb0ef41Sopenharmony_ci Object.defineProperty(obj, 'then', { 1581cb0ef41Sopenharmony_ci get: common.mustCall(() => { 1591cb0ef41Sopenharmony_ci return common.mustCall((resolved, rejected) => { 1601cb0ef41Sopenharmony_ci assert.strictEqual(resolved, undefined); 1611cb0ef41Sopenharmony_ci rejected(_err); 1621cb0ef41Sopenharmony_ci }); 1631cb0ef41Sopenharmony_ci }, 1), // Only 1 call for Promises/A+ compat. 1641cb0ef41Sopenharmony_ci }); 1651cb0ef41Sopenharmony_ci 1661cb0ef41Sopenharmony_ci return obj; 1671cb0ef41Sopenharmony_ci })); 1681cb0ef41Sopenharmony_ci 1691cb0ef41Sopenharmony_ci ee.on('error', common.mustCall((err) => { 1701cb0ef41Sopenharmony_ci assert.strictEqual(err, _err); 1711cb0ef41Sopenharmony_ci process.nextTick(avoidLoopOnRejection); 1721cb0ef41Sopenharmony_ci })); 1731cb0ef41Sopenharmony_ci 1741cb0ef41Sopenharmony_ci ee.emit('something'); 1751cb0ef41Sopenharmony_ci} 1761cb0ef41Sopenharmony_ci 1771cb0ef41Sopenharmony_cifunction avoidLoopOnRejection() { 1781cb0ef41Sopenharmony_ci const ee = new EventEmitter({ captureRejections: true }); 1791cb0ef41Sopenharmony_ci const _err1 = new Error('kaboom'); 1801cb0ef41Sopenharmony_ci const _err2 = new Error('kaboom2'); 1811cb0ef41Sopenharmony_ci ee.on('something', common.mustCall(async (value) => { 1821cb0ef41Sopenharmony_ci throw _err1; 1831cb0ef41Sopenharmony_ci })); 1841cb0ef41Sopenharmony_ci 1851cb0ef41Sopenharmony_ci ee[captureRejectionSymbol] = common.mustCall(async (err) => { 1861cb0ef41Sopenharmony_ci assert.strictEqual(err, _err1); 1871cb0ef41Sopenharmony_ci throw _err2; 1881cb0ef41Sopenharmony_ci }); 1891cb0ef41Sopenharmony_ci 1901cb0ef41Sopenharmony_ci process.removeAllListeners('unhandledRejection'); 1911cb0ef41Sopenharmony_ci 1921cb0ef41Sopenharmony_ci process.once('unhandledRejection', common.mustCall((err) => { 1931cb0ef41Sopenharmony_ci // restore default 1941cb0ef41Sopenharmony_ci process.on('unhandledRejection', (err) => { throw err; }); 1951cb0ef41Sopenharmony_ci 1961cb0ef41Sopenharmony_ci assert.strictEqual(err, _err2); 1971cb0ef41Sopenharmony_ci process.nextTick(avoidLoopOnError); 1981cb0ef41Sopenharmony_ci })); 1991cb0ef41Sopenharmony_ci 2001cb0ef41Sopenharmony_ci ee.emit('something'); 2011cb0ef41Sopenharmony_ci} 2021cb0ef41Sopenharmony_ci 2031cb0ef41Sopenharmony_cifunction avoidLoopOnError() { 2041cb0ef41Sopenharmony_ci const ee = new EventEmitter({ captureRejections: true }); 2051cb0ef41Sopenharmony_ci const _err1 = new Error('kaboom'); 2061cb0ef41Sopenharmony_ci const _err2 = new Error('kaboom2'); 2071cb0ef41Sopenharmony_ci ee.on('something', common.mustCall(async (value) => { 2081cb0ef41Sopenharmony_ci throw _err1; 2091cb0ef41Sopenharmony_ci })); 2101cb0ef41Sopenharmony_ci 2111cb0ef41Sopenharmony_ci ee.on('error', common.mustCall(async (err) => { 2121cb0ef41Sopenharmony_ci assert.strictEqual(err, _err1); 2131cb0ef41Sopenharmony_ci throw _err2; 2141cb0ef41Sopenharmony_ci })); 2151cb0ef41Sopenharmony_ci 2161cb0ef41Sopenharmony_ci process.removeAllListeners('unhandledRejection'); 2171cb0ef41Sopenharmony_ci 2181cb0ef41Sopenharmony_ci process.once('unhandledRejection', common.mustCall((err) => { 2191cb0ef41Sopenharmony_ci // restore default 2201cb0ef41Sopenharmony_ci process.on('unhandledRejection', (err) => { throw err; }); 2211cb0ef41Sopenharmony_ci 2221cb0ef41Sopenharmony_ci assert.strictEqual(err, _err2); 2231cb0ef41Sopenharmony_ci process.nextTick(thenableThatThrows); 2241cb0ef41Sopenharmony_ci })); 2251cb0ef41Sopenharmony_ci 2261cb0ef41Sopenharmony_ci ee.emit('something'); 2271cb0ef41Sopenharmony_ci} 2281cb0ef41Sopenharmony_ci 2291cb0ef41Sopenharmony_cifunction thenableThatThrows() { 2301cb0ef41Sopenharmony_ci const ee = new EventEmitter({ captureRejections: true }); 2311cb0ef41Sopenharmony_ci const _err = new Error('kaboom'); 2321cb0ef41Sopenharmony_ci ee.on('something', common.mustCall((value) => { 2331cb0ef41Sopenharmony_ci const obj = {}; 2341cb0ef41Sopenharmony_ci 2351cb0ef41Sopenharmony_ci Object.defineProperty(obj, 'then', { 2361cb0ef41Sopenharmony_ci get: common.mustCall(() => { 2371cb0ef41Sopenharmony_ci throw _err; 2381cb0ef41Sopenharmony_ci }, 1), // Only 1 call for Promises/A+ compat. 2391cb0ef41Sopenharmony_ci }); 2401cb0ef41Sopenharmony_ci 2411cb0ef41Sopenharmony_ci return obj; 2421cb0ef41Sopenharmony_ci })); 2431cb0ef41Sopenharmony_ci 2441cb0ef41Sopenharmony_ci ee.on('error', common.mustCall((err) => { 2451cb0ef41Sopenharmony_ci assert.strictEqual(err, _err); 2461cb0ef41Sopenharmony_ci process.nextTick(resetCaptureOnThrowInError); 2471cb0ef41Sopenharmony_ci })); 2481cb0ef41Sopenharmony_ci 2491cb0ef41Sopenharmony_ci ee.emit('something'); 2501cb0ef41Sopenharmony_ci} 2511cb0ef41Sopenharmony_ci 2521cb0ef41Sopenharmony_cifunction resetCaptureOnThrowInError() { 2531cb0ef41Sopenharmony_ci const ee = new EventEmitter({ captureRejections: true }); 2541cb0ef41Sopenharmony_ci ee.on('something', common.mustCall(async (value) => { 2551cb0ef41Sopenharmony_ci throw new Error('kaboom'); 2561cb0ef41Sopenharmony_ci })); 2571cb0ef41Sopenharmony_ci 2581cb0ef41Sopenharmony_ci ee.once('error', common.mustCall((err) => { 2591cb0ef41Sopenharmony_ci throw err; 2601cb0ef41Sopenharmony_ci })); 2611cb0ef41Sopenharmony_ci 2621cb0ef41Sopenharmony_ci process.removeAllListeners('uncaughtException'); 2631cb0ef41Sopenharmony_ci 2641cb0ef41Sopenharmony_ci process.once('uncaughtException', common.mustCall((err) => { 2651cb0ef41Sopenharmony_ci process.nextTick(next); 2661cb0ef41Sopenharmony_ci })); 2671cb0ef41Sopenharmony_ci 2681cb0ef41Sopenharmony_ci ee.emit('something'); 2691cb0ef41Sopenharmony_ci 2701cb0ef41Sopenharmony_ci function next() { 2711cb0ef41Sopenharmony_ci process.on('uncaughtException', common.mustNotCall()); 2721cb0ef41Sopenharmony_ci 2731cb0ef41Sopenharmony_ci const _err = new Error('kaboom2'); 2741cb0ef41Sopenharmony_ci ee.on('something2', common.mustCall(async (value) => { 2751cb0ef41Sopenharmony_ci throw _err; 2761cb0ef41Sopenharmony_ci })); 2771cb0ef41Sopenharmony_ci 2781cb0ef41Sopenharmony_ci ee.on('error', common.mustCall((err) => { 2791cb0ef41Sopenharmony_ci assert.strictEqual(err, _err); 2801cb0ef41Sopenharmony_ci 2811cb0ef41Sopenharmony_ci process.removeAllListeners('uncaughtException'); 2821cb0ef41Sopenharmony_ci 2831cb0ef41Sopenharmony_ci // restore default 2841cb0ef41Sopenharmony_ci process.on('uncaughtException', (err) => { throw err; }); 2851cb0ef41Sopenharmony_ci 2861cb0ef41Sopenharmony_ci process.nextTick(argValidation); 2871cb0ef41Sopenharmony_ci })); 2881cb0ef41Sopenharmony_ci 2891cb0ef41Sopenharmony_ci ee.emit('something2'); 2901cb0ef41Sopenharmony_ci } 2911cb0ef41Sopenharmony_ci} 2921cb0ef41Sopenharmony_ci 2931cb0ef41Sopenharmony_cifunction argValidation() { 2941cb0ef41Sopenharmony_ci 2951cb0ef41Sopenharmony_ci function testType(obj) { 2961cb0ef41Sopenharmony_ci const received = obj.constructor.name !== 'Number' ? 2971cb0ef41Sopenharmony_ci `an instance of ${obj.constructor.name}` : 2981cb0ef41Sopenharmony_ci `type number (${obj})`; 2991cb0ef41Sopenharmony_ci 3001cb0ef41Sopenharmony_ci assert.throws(() => new EventEmitter({ captureRejections: obj }), { 3011cb0ef41Sopenharmony_ci code: 'ERR_INVALID_ARG_TYPE', 3021cb0ef41Sopenharmony_ci name: 'TypeError', 3031cb0ef41Sopenharmony_ci message: 'The "options.captureRejections" property must be of type ' + 3041cb0ef41Sopenharmony_ci `boolean. Received ${received}`, 3051cb0ef41Sopenharmony_ci }); 3061cb0ef41Sopenharmony_ci 3071cb0ef41Sopenharmony_ci assert.throws(() => EventEmitter.captureRejections = obj, { 3081cb0ef41Sopenharmony_ci code: 'ERR_INVALID_ARG_TYPE', 3091cb0ef41Sopenharmony_ci name: 'TypeError', 3101cb0ef41Sopenharmony_ci message: 'The "EventEmitter.captureRejections" property must be of ' + 3111cb0ef41Sopenharmony_ci `type boolean. Received ${received}`, 3121cb0ef41Sopenharmony_ci }); 3131cb0ef41Sopenharmony_ci } 3141cb0ef41Sopenharmony_ci 3151cb0ef41Sopenharmony_ci testType([]); 3161cb0ef41Sopenharmony_ci testType({ hello: 42 }); 3171cb0ef41Sopenharmony_ci testType(42); 3181cb0ef41Sopenharmony_ci} 3191cb0ef41Sopenharmony_ci 3201cb0ef41Sopenharmony_cicaptureRejections(); 321