'use strict'; const common = require('../common'); const assert = require('assert'); const domain = require('domain'); // setImmediate should run clear its queued cbs once per event loop turn // but immediates queued while processing the current queue should happen // on the next turn of the event loop. // In addition, if any setImmediate throws, the rest of the queue should // be processed after all error handling is resolved, but that queue // should not include any setImmediate calls scheduled after the // processing of the queue started. let threw = false; let stage = -1; const QUEUE = 10; const errObj = { name: 'Error', message: 'setImmediate Err' }; process.once('uncaughtException', common.mustCall((err, errorOrigin) => { assert.strictEqual(errorOrigin, 'uncaughtException'); assert.strictEqual(stage, 0); common.expectsError(errObj)(err); })); const d1 = domain.create(); d1.once('error', common.expectsError(errObj)); d1.once('error', () => assert.strictEqual(stage, 0)); const run = common.mustCall((callStage) => { assert(callStage >= stage); stage = callStage; if (threw) return; setImmediate(run, 2); }, QUEUE * 3); for (let i = 0; i < QUEUE; i++) setImmediate(run, 0); setImmediate(() => { threw = true; process.nextTick(() => assert.strictEqual(stage, 1)); throw new Error('setImmediate Err'); }); d1.run(() => setImmediate(() => { throw new Error('setImmediate Err'); })); for (let i = 0; i < QUEUE; i++) setImmediate(run, 1);