1'use strict'; 2 3const common = require('../common'); 4const assert = require('assert'); 5const domain = require('domain'); 6const EventEmitter = require('events'); 7 8// Make sure that the domains stack and the active domain is setup properly when 9// a domain's error handler is called due to an error event being emitted. 10// More specifically, we want to test that: 11// - the active domain in the domain's error handler is//not* that domain,//but* 12// the active domain is a any direct parent domain at the time the error was 13// emitted. 14// - the domains stack in the domain's error handler does//not* include that 15// domain, *but* it includes all parents of that domain when the error was 16// emitted. 17const d1 = domain.create(); 18const d2 = domain.create(); 19const d3 = domain.create(); 20 21function checkExpectedDomains(err) { 22 // First, check that domains stack and active domain is as expected when the 23 // event handler is called synchronously via ee.emit('error'). 24 if (domain._stack.length !== err.expectedStackLength) { 25 console.error('expected domains stack length of %d, but instead is %d', 26 err.expectedStackLength, domain._stack.length); 27 process.exit(1); 28 } 29 30 if (process.domain !== err.expectedActiveDomain) { 31 console.error('expected active domain to be %j, but instead is %j', 32 err.expectedActiveDomain, process.domain); 33 process.exit(1); 34 } 35 36 // Then make sure that the domains stack and active domain is setup as 37 // expected when executing a callback scheduled via nextTick from the error 38 // handler. 39 process.nextTick(() => { 40 const expectedStackLengthInNextTickCb = 41 err.expectedStackLength > 0 ? 1 : 0; 42 if (domain._stack.length !== expectedStackLengthInNextTickCb) { 43 console.error('expected stack length in nextTick cb to be %d, ' + 44 'but instead is %d', expectedStackLengthInNextTickCb, 45 domain._stack.length); 46 process.exit(1); 47 } 48 49 const expectedActiveDomainInNextTickCb = 50 expectedStackLengthInNextTickCb === 0 ? undefined : 51 err.expectedActiveDomain; 52 if (process.domain !== expectedActiveDomainInNextTickCb) { 53 console.error('expected active domain in nextTick cb to be %j, ' + 54 'but instead is %j', expectedActiveDomainInNextTickCb, 55 process.domain); 56 process.exit(1); 57 } 58 }); 59} 60 61d1.on('error', common.mustCall((err) => { 62 checkExpectedDomains(err); 63}, 2)); 64 65d2.on('error', common.mustCall((err) => { 66 checkExpectedDomains(err); 67}, 2)); 68 69d3.on('error', common.mustCall((err) => { 70 checkExpectedDomains(err); 71}, 1)); 72 73d1.run(() => { 74 const ee = new EventEmitter(); 75 assert.strictEqual(process.domain, d1); 76 assert.strictEqual(domain._stack.length, 1); 77 78 const err = new Error('oops'); 79 err.expectedStackLength = 0; 80 err.expectedActiveDomain = null; 81 ee.emit('error', err); 82 83 assert.strictEqual(process.domain, d1); 84 assert.strictEqual(domain._stack.length, 1); 85}); 86 87d1.run(() => { 88 d1.run(() => { 89 const ee = new EventEmitter(); 90 91 assert.strictEqual(process.domain, d1); 92 assert.strictEqual(domain._stack.length, 2); 93 94 const err = new Error('oops'); 95 err.expectedStackLength = 0; 96 err.expectedActiveDomain = null; 97 ee.emit('error', err); 98 99 assert.strictEqual(process.domain, d1); 100 assert.strictEqual(domain._stack.length, 2); 101 }); 102}); 103 104d1.run(() => { 105 d2.run(() => { 106 const ee = new EventEmitter(); 107 108 assert.strictEqual(process.domain, d2); 109 assert.strictEqual(domain._stack.length, 2); 110 111 const err = new Error('oops'); 112 err.expectedStackLength = 1; 113 err.expectedActiveDomain = d1; 114 ee.emit('error', err); 115 116 assert.strictEqual(process.domain, d2); 117 assert.strictEqual(domain._stack.length, 2); 118 }); 119}); 120 121d1.run(() => { 122 d2.run(() => { 123 d2.run(() => { 124 const ee = new EventEmitter(); 125 126 assert.strictEqual(process.domain, d2); 127 assert.strictEqual(domain._stack.length, 3); 128 129 const err = new Error('oops'); 130 err.expectedStackLength = 1; 131 err.expectedActiveDomain = d1; 132 ee.emit('error', err); 133 134 assert.strictEqual(process.domain, d2); 135 assert.strictEqual(domain._stack.length, 3); 136 }); 137 }); 138}); 139 140d3.run(() => { 141 d1.run(() => { 142 d3.run(() => { 143 d3.run(() => { 144 const ee = new EventEmitter(); 145 146 assert.strictEqual(process.domain, d3); 147 assert.strictEqual(domain._stack.length, 4); 148 149 const err = new Error('oops'); 150 err.expectedStackLength = 2; 151 err.expectedActiveDomain = d1; 152 ee.emit('error', err); 153 154 assert.strictEqual(process.domain, d3); 155 assert.strictEqual(domain._stack.length, 4); 156 }); 157 }); 158 }); 159}); 160