| '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); |