-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsafer-emitter.ts
56 lines (51 loc) · 1.88 KB
/
safer-emitter.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import EventEmitter from 'events';
export class SaferEmitter extends EventEmitter {
emit(type: string, ...args: unknown[]) {
let doError = type === 'error';
let events = (this as any)._events;
if (events !== undefined) doError = doError && events.error === undefined;
else if (!doError) return false;
// If there is no 'error' event listener then throw.
if (doError) {
let er;
if (args.length > 0) er = args[0];
if (er instanceof Error) {
// Note: The comments on the `throw` lines are intentional, they show
// up in Node's output if this results in an unhandled exception.
throw er; // Unhandled 'error' event
}
// At least give some kind of context to the user
let err = new Error('Unhandled error.' + (er ? ' (' + (er as any).message + ')' : ''));
(err as any).context = er;
throw err; // Unhandled 'error' event
}
let handler = events[type];
if (handler === undefined) return false;
if (typeof handler === 'function') {
try {
Reflect.apply(handler, this, args);
} catch (error) {
events[type] = undefined;
}
} else {
let listeners = [...handler];
listeners
.filter((e) => {
try {
e.call;
} catch (error) {
return false;
}
return true;
})
.forEach((listener) => {
try {
Reflect.apply(listener, this, args);
} catch (error) {
console.error(error);
}
});
}
return true;
}
}