162 lines
4.6 KiB
JavaScript
162 lines
4.6 KiB
JavaScript
|
'use strict';
|
||
|
|
||
|
const common = require('../common');
|
||
|
const assert = require('assert');
|
||
|
const domain = require('domain');
|
||
|
const EventEmitter = require('events');
|
||
|
|
||
|
/*
|
||
|
* Make sure that the domains stack and the active domain is setup properly when
|
||
|
* a domain's error handler is called due to an error event being emitted.
|
||
|
* More specifically, we want to test that:
|
||
|
* - the active domain in the domain's error handler is *not* that domain, *but*
|
||
|
* the active domain is a any direct parent domain at the time the error was
|
||
|
* emitted.
|
||
|
* - the domains stack in the domain's error handler does *not* include that
|
||
|
* domain, *but* it includes all parents of that domain when the error was
|
||
|
* emitted.
|
||
|
*/
|
||
|
const d1 = domain.create();
|
||
|
const d2 = domain.create();
|
||
|
const d3 = domain.create();
|
||
|
|
||
|
function checkExpectedDomains(err) {
|
||
|
// First, check that domains stack and active domain is as expected when the
|
||
|
// event handler is called synchronously via ee.emit('error').
|
||
|
if (domain._stack.length !== err.expectedStackLength) {
|
||
|
console.error('expected domains stack length of %d, but instead is %d',
|
||
|
err.expectedStackLength, domain._stack.length);
|
||
|
process.exit(1);
|
||
|
}
|
||
|
|
||
|
if (process.domain !== err.expectedActiveDomain) {
|
||
|
console.error('expected active domain to be %j, but instead is %j',
|
||
|
err.expectedActiveDomain, process.domain);
|
||
|
process.exit(1);
|
||
|
}
|
||
|
|
||
|
// Then make sure that the domains stack and active domain is setup as
|
||
|
// expected when executing a callback scheduled via nextTick from the error
|
||
|
// handler.
|
||
|
process.nextTick(() => {
|
||
|
const expectedStackLengthInNextTickCb =
|
||
|
err.expectedStackLength > 0 ? 1 : 0;
|
||
|
if (domain._stack.length !== expectedStackLengthInNextTickCb) {
|
||
|
console.error('expected stack length in nextTick cb to be %d, ' +
|
||
|
'but instead is %d', expectedStackLengthInNextTickCb,
|
||
|
domain._stack.length);
|
||
|
process.exit(1);
|
||
|
}
|
||
|
|
||
|
const expectedActiveDomainInNextTickCb =
|
||
|
expectedStackLengthInNextTickCb === 0 ? undefined :
|
||
|
err.expectedActiveDomain;
|
||
|
if (process.domain !== expectedActiveDomainInNextTickCb) {
|
||
|
console.error('expected active domain in nextTick cb to be %j, ' +
|
||
|
'but instead is %j', expectedActiveDomainInNextTickCb,
|
||
|
process.domain);
|
||
|
process.exit(1);
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
d1.on('error', common.mustCall((err) => {
|
||
|
checkExpectedDomains(err);
|
||
|
}, 2));
|
||
|
|
||
|
d2.on('error', common.mustCall((err) => {
|
||
|
checkExpectedDomains(err);
|
||
|
}, 2));
|
||
|
|
||
|
d3.on('error', common.mustCall((err) => {
|
||
|
checkExpectedDomains(err);
|
||
|
}, 1));
|
||
|
|
||
|
d1.run(() => {
|
||
|
const ee = new EventEmitter();
|
||
|
assert.strictEqual(process.domain, d1);
|
||
|
assert.strictEqual(domain._stack.length, 1);
|
||
|
|
||
|
const err = new Error('oops');
|
||
|
err.expectedStackLength = 0;
|
||
|
err.expectedActiveDomain = null;
|
||
|
ee.emit('error', err);
|
||
|
|
||
|
assert.strictEqual(process.domain, d1);
|
||
|
assert.strictEqual(domain._stack.length, 1);
|
||
|
});
|
||
|
|
||
|
d1.run(() => {
|
||
|
d1.run(() => {
|
||
|
const ee = new EventEmitter();
|
||
|
|
||
|
assert.strictEqual(process.domain, d1);
|
||
|
assert.strictEqual(domain._stack.length, 2);
|
||
|
|
||
|
const err = new Error('oops');
|
||
|
err.expectedStackLength = 0;
|
||
|
err.expectedActiveDomain = null;
|
||
|
ee.emit('error', err);
|
||
|
|
||
|
assert.strictEqual(process.domain, d1);
|
||
|
assert.strictEqual(domain._stack.length, 2);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
d1.run(() => {
|
||
|
d2.run(() => {
|
||
|
const ee = new EventEmitter();
|
||
|
|
||
|
assert.strictEqual(process.domain, d2);
|
||
|
assert.strictEqual(domain._stack.length, 2);
|
||
|
|
||
|
const err = new Error('oops');
|
||
|
err.expectedStackLength = 1;
|
||
|
err.expectedActiveDomain = d1;
|
||
|
ee.emit('error', err);
|
||
|
|
||
|
assert.strictEqual(process.domain, d2);
|
||
|
assert.strictEqual(domain._stack.length, 2);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
d1.run(() => {
|
||
|
d2.run(() => {
|
||
|
d2.run(() => {
|
||
|
const ee = new EventEmitter();
|
||
|
|
||
|
assert.strictEqual(process.domain, d2);
|
||
|
assert.strictEqual(domain._stack.length, 3);
|
||
|
|
||
|
const err = new Error('oops');
|
||
|
err.expectedStackLength = 1;
|
||
|
err.expectedActiveDomain = d1;
|
||
|
ee.emit('error', err);
|
||
|
|
||
|
assert.strictEqual(process.domain, d2);
|
||
|
assert.strictEqual(domain._stack.length, 3);
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
|
||
|
d3.run(() => {
|
||
|
d1.run(() => {
|
||
|
d3.run(() => {
|
||
|
d3.run(() => {
|
||
|
const ee = new EventEmitter();
|
||
|
|
||
|
assert.strictEqual(process.domain, d3);
|
||
|
assert.strictEqual(domain._stack.length, 4);
|
||
|
|
||
|
const err = new Error('oops');
|
||
|
err.expectedStackLength = 2;
|
||
|
err.expectedActiveDomain = d1;
|
||
|
ee.emit('error', err);
|
||
|
|
||
|
assert.strictEqual(process.domain, d3);
|
||
|
assert.strictEqual(domain._stack.length, 4);
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
});
|