From 795f60c40f20ec13a02214eb6344e8fb64cedbff Mon Sep 17 00:00:00 2001 From: platfowner Date: Wed, 14 Aug 2024 14:55:12 +0900 Subject: [PATCH 1/3] Tweak exception messages --- event-handler/index.js | 4 ++-- event-handler/state-event-tree-manager.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/event-handler/index.js b/event-handler/index.js index d4f166a76..8231652d9 100644 --- a/event-handler/index.js +++ b/event-handler/index.js @@ -305,12 +305,12 @@ class EventHandler { const eventFilter = this.eventFilters[eventFilterId]; if (!eventFilter) { throw new EventHandlerError(EventHandlerErrorCode.NO_MATCHED_FILTERS, - `Can't find filter by filter id`, eventFilterId); + `Can't find filter by filter id (eventFilterId: ${eventFilterId})`); } delete this.eventFilters[eventFilterId]; if (!this.eventTypeToEventFilterIds[eventFilter.type].delete(eventFilterId)) { throw new EventHandlerError(EventHandlerErrorCode.MISSING_FILTER_ID_IN_TYPE_TO_FILTER_IDS, - `Can't delete filter Id from eventTypeToEventFilterIds (${eventFilterId})`); + `Can't delete filter Id from eventTypeToEventFilterIds (eventFilterId: ${eventFilterId})`); } if (eventFilter.type === BlockchainEventTypes.VALUE_CHANGED) { this.stateEventTreeManager.deregisterEventFilterId(eventFilterId); diff --git a/event-handler/state-event-tree-manager.js b/event-handler/state-event-tree-manager.js index 56db0db90..02354d0a4 100644 --- a/event-handler/state-event-tree-manager.js +++ b/event-handler/state-event-tree-manager.js @@ -103,7 +103,7 @@ class StateEventTreeManager { if (!parsedPath) { throw new EventHandlerError( EventHandlerErrorCode.MISSING_FILTER_ID_IN_FILTER_ID_TO_PARSED_PATH, - `Can't find parsedPath from filterIdToParsedPath (${filterId})` + `Can't find parsedPath from filterIdToParsedPath (filterId: ${filterId})` ); } delete this.filterIdToParsedPath[filterId]; From 9db9e7c28370773e0a60c8991caba9a75a283d7b Mon Sep 17 00:00:00 2001 From: platfowner Date: Wed, 14 Aug 2024 15:32:18 +0900 Subject: [PATCH 2/3] Do not use exceptions for deregistration errors --- common/result-code.js | 14 ++++---- event-handler/event-channel-manager.js | 43 +++++++++-------------- event-handler/index.js | 19 ++++++---- event-handler/state-event-tree-manager.js | 16 ++++----- 4 files changed, 45 insertions(+), 47 deletions(-) diff --git a/common/result-code.js b/common/result-code.js index a7ee44e92..e24646f6a 100644 --- a/common/result-code.js +++ b/common/result-code.js @@ -217,15 +217,15 @@ const EventHandlerErrorCode = { MISSING_CONFIG_IN_MSG_DATA: 70007, DUPLICATED_GLOBAL_FILTER_ID: 70008, INVALID_EVENT_TYPE_IN_VALIDATE_FUNC: 70009, - NO_MATCHED_FILTERS: 70010, - MISSING_FILTER_ID_IN_TYPE_TO_FILTER_IDS: 70011, - PARSING_GLOBAL_FILTER_ID_FAILURE: 70012, + NO_MATCHED_FILTERS: 70010, // Deprecated (2024-08-14). + MISSING_FILTER_ID_IN_TYPE_TO_FILTER_IDS: 70011, // Deprecated (2024-08-14) + PARSING_GLOBAL_FILTER_ID_FAILURE: 70012, // Deprecated (2024-08-14). DUPLICATED_CHANNEL_ID: 70013, EVENT_CHANNEL_EXCEEDS_SIZE_LIMIT: 70014, EVENT_FILTER_EXCEEDS_SIZE_LIMIT: 70015, EVENT_FILTER_EXCEEDS_SIZE_LIMIT_PER_CHANNEL: 70016, FAILED_TO_REGISTER_FILTER: 70020, - FAILED_TO_DEREGISTER_FILTER: 70030, + FAILED_TO_DEREGISTER_FILTER: 70030, // Deprecated (2024-08-14). INVALID_CUSTOM_CLIENT_ID: 70040, // BLOCK_FINALIZED (701XX) NEGATIVE_BLOCK_NUMBER: 70100, @@ -234,9 +234,9 @@ const EventHandlerErrorCode = { MISSING_PATH_IN_CONFIG: 70200, INVALID_FORMAT_PATH: 70201, // VALUE_CHANGED & StateEventTreeManager (7025X) - MISSING_FILTER_ID_IN_FILTER_ID_TO_PARSED_PATH: 70250, - MISSING_FILTER_ID_SET: 70251, - MISSING_FILTER_ID_IN_FILTER_ID_SET: 70252, + MISSING_FILTER_ID_IN_FILTER_ID_TO_PARSED_PATH: 70250, // Deprecated (2024-08-14). + MISSING_FILTER_ID_SET: 70251, // Deprecated (2024-08-14). + MISSING_FILTER_ID_IN_FILTER_ID_SET: 70252, // Deprecated (2024-08-14). // TX_STATE_CHANGED (703XX) MISSING_TX_HASH_IN_CONFIG: 70300, INVALID_TX_HASH: 70301, diff --git a/event-handler/event-channel-manager.js b/event-handler/event-channel-manager.js index cd5487f13..d0c9d0892 100644 --- a/event-handler/event-channel-manager.js +++ b/event-handler/event-channel-manager.js @@ -236,25 +236,15 @@ class EventChannelManager { deregisterFilter(channel, clientFilterId) { const filter = this.node.eh.deregisterEventFilter(clientFilterId, channel.id); + if (!filter) { + return; + } channel.deleteEventFilterId(filter.id); delete this.filterIdToChannelId[filter.id]; } deregisterFilterAndEmitEvent(channel, clientFilterId, filterDeletionReason) { - const LOG_HEADER = 'deregisterFilterAndEmitEvent'; - try { - this.deregisterFilter(channel, clientFilterId); - } catch (err) { - logger.error(`[${LOG_HEADER}] Can't deregister event filter ` + - `(clientFilterId: ${clientFilterId}, channelId: ${channel.id}, ` + - `err: ${err.message} at ${err.stack})`); - throw new EventHandlerError( - EventHandlerErrorCode.FAILED_TO_DEREGISTER_FILTER, - `Failed to deregister filter with filter ID: ${clientFilterId} ` + - `due to error: ${err.message}`, - clientFilterId - ); - } + this.deregisterFilter(channel, clientFilterId); const blockchainEvent = new BlockchainEvent( BlockchainEventTypes.FILTER_DELETED, { @@ -344,6 +334,9 @@ class EventChannelManager { // TODO(ehgmsdk20): reuse same object for memory const eventObj = event.toObject(); const clientFilterId = this.node.eh.getClientFilterIdFromGlobalFilterId(eventFilterId); + if (!clientFilterId) { + return; + } Object.assign(eventObj, { filter_id: clientFilterId }); this.transmitEventObj(channel, eventObj); } @@ -369,20 +362,18 @@ class EventChannelManager { closeChannel(channel) { const LOG_HEADER = 'closeChannel'; - try { - logger.info(`[${LOG_HEADER}] Closing channel ${channel.id}`); - channel.webSocket.terminate(); - const filterIds = channel.getAllFilterIds(); - for (const filterId of filterIds) { - const clientFilterId = this.node.eh.getClientFilterIdFromGlobalFilterId(filterId); - // NOTE(ehgmsdk20): Do not emit filter_deleted event because the channel is already closed. - this.deregisterFilter(channel, clientFilterId); + logger.info(`[${LOG_HEADER}] Closing channel ${channel.id}`); + channel.webSocket.terminate(); + const filterIds = channel.getAllFilterIds(); + for (const filterId of filterIds) { + const clientFilterId = this.node.eh.getClientFilterIdFromGlobalFilterId(filterId); + if (!clientFilterId) { + continue; } - delete this.channels[channel.id]; - } catch (err) { - logger.error(`[${LOG_HEADER}] Error while closing channel (channelId: ${channel.id}, ` + - `message:${err.message})`); + // NOTE(ehgmsdk20): Do not emit filter_deleted event because the channel is already closed. + this.deregisterFilter(channel, clientFilterId); } + delete this.channels[channel.id]; } startHeartbeat(wsServer) { diff --git a/event-handler/index.js b/event-handler/index.js index 8231652d9..1f4d8d1a3 100644 --- a/event-handler/index.js +++ b/event-handler/index.js @@ -191,6 +191,9 @@ class EventHandler { if (isEndState(afterState)) { const channel = this.eventChannelManager.getChannelByEventFilterId(eventFilterId); const clientFilterId = this.getClientFilterIdFromGlobalFilterId(eventFilterId); + if (!clientFilterId) { + continue; + } this.eventChannelManager.deregisterFilterAndEmitEvent( channel, clientFilterId, FilterDeletionReasons.END_STATE_REACHED ); @@ -213,6 +216,9 @@ class EventHandler { this.eventFilterIdToTimeoutCallback.set(eventFilterId, setTimeout(() => { const channel = this.eventChannelManager.getChannelByEventFilterId(eventFilterId); const clientFilterId = this.getClientFilterIdFromGlobalFilterId(eventFilterId); + if (!clientFilterId) { + return; + } this.eventChannelManager.deregisterFilterAndEmitEvent( channel, clientFilterId, FilterDeletionReasons.FILTER_TIMEOUT ); @@ -220,10 +226,11 @@ class EventHandler { } getClientFilterIdFromGlobalFilterId(globalFilterId) { + const LOG_HEADER = 'getClientFilterIdFromGlobalFilterId'; const clientFilterId = globalFilterId.split(':')[1]; if (!clientFilterId) { - throw new EventHandlerError(EventHandlerErrorCode.PARSING_GLOBAL_FILTER_ID_FAILURE, - `Can't get client filter ID from global filter ID (globalFilterId: ${globalFilterId})`); + logger.error(`[${LOG_HEADER}] Can't get client filter ID from global filter ID (globalFilterId: ${globalFilterId})`); + return null; } return clientFilterId; } @@ -304,13 +311,13 @@ class EventHandler { const eventFilterId = this.getGlobalFilterId(channelId, clientFilterId); const eventFilter = this.eventFilters[eventFilterId]; if (!eventFilter) { - throw new EventHandlerError(EventHandlerErrorCode.NO_MATCHED_FILTERS, - `Can't find filter by filter id (eventFilterId: ${eventFilterId})`); + logger.error(`[${LOG_HEADER}] Can't find filter by filter id (eventFilterId: ${eventFilterId})`); + return null; } delete this.eventFilters[eventFilterId]; if (!this.eventTypeToEventFilterIds[eventFilter.type].delete(eventFilterId)) { - throw new EventHandlerError(EventHandlerErrorCode.MISSING_FILTER_ID_IN_TYPE_TO_FILTER_IDS, - `Can't delete filter Id from eventTypeToEventFilterIds (eventFilterId: ${eventFilterId})`); + logger.error(`[${LOG_HEADER}] Can't delete filter Id from eventTypeToEventFilterIds (eventFilterId: ${eventFilterId})`); + return null; } if (eventFilter.type === BlockchainEventTypes.VALUE_CHANGED) { this.stateEventTreeManager.deregisterEventFilterId(eventFilterId); diff --git a/event-handler/state-event-tree-manager.js b/event-handler/state-event-tree-manager.js index 02354d0a4..666f853b0 100644 --- a/event-handler/state-event-tree-manager.js +++ b/event-handler/state-event-tree-manager.js @@ -87,24 +87,24 @@ class StateEventTreeManager { } deleteFilterIdFromEventNode(eventNode, filterId) { + const LOG_HEADER = 'deleteFilterIdFromEventNode'; if (!eventNode || !eventNode.filterIdSet) { - throw new EventHandlerError(EventHandlerErrorCode.MISSING_FILTER_ID_SET, - `Can't find filterIdSet (eventNode: ${JSON.stringify(eventNode)})`); + logger.error(`[${LOG_HEADER}] Can't find filterIdSet (eventNode: ${JSON.stringify(eventNode)})`); + return; } if (!eventNode.filterIdSet.delete(filterId)) { - throw new EventHandlerError(EventHandlerErrorCode.MISSING_FILTER_ID_IN_FILTER_ID_SET, - `Can't delete filter id (${filterId}) from filterIdSet ` + + logger.error(`[${LOG_HEADER}] Can't delete filter id (${filterId}) from filterIdSet ` + `(${JSON.stringify(eventNode.filterIdSet.values())})`); + return; } } deregisterEventFilterId(filterId) { + const LOG_HEADER = 'deregisterEventFilterId'; const parsedPath = this.filterIdToParsedPath[filterId]; if (!parsedPath) { - throw new EventHandlerError( - EventHandlerErrorCode.MISSING_FILTER_ID_IN_FILTER_ID_TO_PARSED_PATH, - `Can't find parsedPath from filterIdToParsedPath (filterId: ${filterId})` - ); + logger.error(`[${LOG_HEADER}] Can't find parsedPath from filterIdToParsedPath (filterId: ${filterId})`); + return; } delete this.filterIdToParsedPath[filterId]; From 895752d887a7b1613d3b692a27dae0296feeea51 Mon Sep 17 00:00:00 2001 From: platfowner Date: Wed, 14 Aug 2024 17:10:27 +0900 Subject: [PATCH 3/3] Update tests for deregistration --- test/integration/event_handler.test.js | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/test/integration/event_handler.test.js b/test/integration/event_handler.test.js index c0fc19b7f..db4f1fb1a 100644 --- a/test/integration/event_handler.test.js +++ b/test/integration/event_handler.test.js @@ -254,26 +254,6 @@ describe('Event Handler Test', function() { deregisterFilter(wsClient, filterId); }); - it('Deregister filter already deregisterd filter', function(done) { - // Deregister filter - wsClient.on('message', (message) => { - try { - const parsedMessage = JSON.parse(message); - const messageType = parsedMessage.type; - const errorCode = _.get(parsedMessage, 'data.code'); - const errorMessage = _.get(parsedMessage, 'data.message'); - if (messageType === BlockchainEventMessageTypes.EMIT_ERROR) { - expect(errorCode).to.equal(EventHandlerErrorCode.FAILED_TO_DEREGISTER_FILTER); - expect(errorMessage).to.equal(`Failed to deregister filter with filter ID: ${filterId} due to error: Can't find filter by filter id`) - done(); - } - } catch (err) { - done(err); - } - }); - deregisterFilter(wsClient, filterId); - }); - it('Register too many filters', function(done) { let exceededCnt = 0; wsClient.on('message', (message) => {