diff --git a/src/cdp/connection.ts b/src/cdp/connection.ts index ade3b967d..ebe69b5c1 100644 --- a/src/cdp/connection.ts +++ b/src/cdp/connection.ts @@ -105,9 +105,12 @@ export default class Connection { if (!session) { const disposedDate = this._disposedSessions.get(object.sessionId); if (!disposedDate) { - throw new Error( - `Unknown session id: ${object.sessionId} while processing: ${object.method}`, + this.logger.warn( + LogTag.Internal, + 'Got message for an unknown session', + { sessionId: object.sessionId, method: object.method }, ); + return; // We just ignore messages for unknown sessions } else { const secondsAgo = (Date.now() - disposedDate.getTime()) / 1000.0; this.logger.warn( diff --git a/src/common/events.test.ts b/src/common/events.test.ts new file mode 100644 index 000000000..693d0de03 --- /dev/null +++ b/src/common/events.test.ts @@ -0,0 +1,27 @@ +/*--------------------------------------------------------- + * Copyright (C) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------*/ + +import { expect } from 'chai'; +import { EventEmitter } from './events'; + +describe('EventEmitter', () => { + it('keeps delivering events after a listener throws', () => { + const emitter = new EventEmitter(); + const delivered: string[] = []; + + emitter.event(event => { + if (event === 'throws') { + throw new Error('listener error'); + } + + delivered.push(event); + }); + + emitter.fire('before'); + expect(() => emitter.fire('throws')).to.throw('listener error'); + emitter.fire('after'); + + expect(delivered).to.deep.equal(['before', 'after']); + }); +}); diff --git a/src/common/events.ts b/src/common/events.ts index aa7d9f7fd..cdcaa47fa 100644 --- a/src/common/events.ts +++ b/src/common/events.ts @@ -57,11 +57,14 @@ export class EventEmitter implements IDisposable { if (!this._deliveryQueue) this._deliveryQueue = []; for (const data of this._listeners) this._deliveryQueue.push({ data, event }); if (!dispatch) return; - for (let index = 0; index < this._deliveryQueue.length; index++) { - const { data, event } = this._deliveryQueue[index]; - data.listener.call(data.thisArg, event); + try { + for (let index = 0; index < this._deliveryQueue.length; index++) { + const { data, event } = this._deliveryQueue[index]; + data.listener.call(data.thisArg, event); + } + } finally { + this._deliveryQueue = undefined; } - this._deliveryQueue = undefined; } dispose() {