File tree Expand file tree Collapse file tree 2 files changed +34
-0
lines changed Expand file tree Collapse file tree 2 files changed +34
-0
lines changed Original file line number Diff line number Diff line change @@ -23,6 +23,10 @@ class EventSource extends EventEmitter {
2323 doTheThing ( ) {
2424 this . emit ( EVENTNAME , "foo" , "bar" ) ;
2525 }
26+
27+ doAnError ( ) {
28+ this . emit ( 'error' ) ;
29+ }
2630}
2731
2832class EventTarget extends EventEmitter {
@@ -46,4 +50,23 @@ describe("ReEmitter", function() {
4650 // also the source object of the event which re-emitter adds
4751 expect ( handler ) . toHaveBeenCalledWith ( "foo" , "bar" , src ) ;
4852 } ) ;
53+
54+ it ( "Doesn't throw if no handler for 'error' event" , function ( ) {
55+ const src = new EventSource ( ) ;
56+ const tgt = new EventTarget ( ) ;
57+
58+ const reEmitter = new ReEmitter ( tgt ) ;
59+ reEmitter . reEmit ( src , [ 'error' ] ) ;
60+
61+ // without the workaround in ReEmitter, this would throw
62+ src . doAnError ( ) ;
63+
64+ const handler = jest . fn ( ) ;
65+ tgt . on ( 'error' , handler ) ;
66+
67+ src . doAnError ( ) ;
68+
69+ // Now we've attached an error handler, it should be called
70+ expect ( handler ) . toHaveBeenCalled ( ) ;
71+ } ) ;
4972} ) ;
Original file line number Diff line number Diff line change @@ -31,6 +31,17 @@ export class ReEmitter {
3131 // such as read receipt listeners on the client class which won't have the context
3232 // of the room.
3333 const forSource = ( ...args ) => {
34+ // EventEmitter special cases 'error' to make the emit function throw if no
35+ // handler is attached, which sort of makes sense for making sure that something
36+ // handles an error, but for re-emitting, there could be a listener on the original
37+ // source object so the test doesn't really work. We *could* try to replicate the
38+ // same logic and throw if there is no listener on either the source or the target,
39+ // but this behaviour is fairly undesireable for us anyway: the main place we throw
40+ // 'error' events is for calls, where error events are usually emitted some time
41+ // later by a different part of the code where 'emit' throwing because the app hasn't
42+ // added an error handler isn't terribly helpful. (A better fix in retrospect may
43+ // have been to just avoid using the event name 'error', but backwards compat...)
44+ if ( eventName === 'error' && this . target . listenerCount ( 'error' ) === 0 ) return ;
3445 this . target . emit ( eventName , ...args , source ) ;
3546 } ;
3647 source . on ( eventName , forSource ) ;
You can’t perform that action at this time.
0 commit comments