diff --git a/workers/grouper/src/data-filter.ts b/workers/grouper/src/data-filter.ts index 2345b8e5..d88b24e3 100644 --- a/workers/grouper/src/data-filter.ts +++ b/workers/grouper/src/data-filter.ts @@ -1,11 +1,17 @@ import type { EventAddons, EventData } from '@hawk.so/types'; import { unsafeFields } from '../../../lib/utils/unsafeFields'; +import { rightTrim } from '../../../lib/utils/string'; /** * Maximum depth for object traversal to prevent excessive memory allocations */ const MAX_TRAVERSAL_DEPTH = 20; +/** + * Maximum length for event title + */ +const MAX_TITLE_LENGTH = 1000; + /** * Recursively iterate through object and call function on each key * @@ -142,6 +148,20 @@ export default class DataFilter { }); } + /** + * Trim event title to the maximum allowed length. + * It mutates the original object. + * + * Should be called before hashing so the hash and the stored title stay consistent. + * + * @param event - event to process + */ + public trimEventTitle(event: EventData): void { + if (typeof event.title === 'string') { + event.title = rightTrim(event.title, MAX_TITLE_LENGTH); + } + } + /** * Recursively iterates object and applies filtering to its entries * diff --git a/workers/grouper/src/index.ts b/workers/grouper/src/index.ts index 8203e8d3..845c5590 100644 --- a/workers/grouper/src/index.ts +++ b/workers/grouper/src/index.ts @@ -59,7 +59,7 @@ const DB_DUPLICATE_KEY_ERROR = '11000'; const DAILY_METRICS_RETENTION_DAYS = 90; /** - * Maximum length for backtrace code line or title + * Maximum length for backtrace code line */ const MAX_CODE_LINE_LENGTH = 140; @@ -209,6 +209,11 @@ export default class GrouperWorker extends Worker { }; } + /** + * Trim title before hashing so hash and stored title stay consistent + */ + this.dataFilter.trimEventTitle(task.payload); + let uniqueEventHash = await session.measureStep('hash', () => this.getUniqueEventHash(task)); let existedEvent: GroupedEventDBScheme; let repetitionId = null; diff --git a/workers/grouper/tests/index.test.ts b/workers/grouper/tests/index.test.ts index c75351a9..18a7dd36 100644 --- a/workers/grouper/tests/index.test.ts +++ b/workers/grouper/tests/index.test.ts @@ -173,6 +173,20 @@ describe('GrouperWorker', () => { expect(await eventsCollection.find().count()).toBe(1); }); + test('Should trim event title to the maximum length before saving', async () => { + const longTitle = 'A'.repeat(5000); + + await worker.handle(generateTask({ title: longTitle })); + + const savedEvent = await eventsCollection.findOne({}); + + /** + * 1000 chars + ellipsis + */ + expect(savedEvent.payload.title.length).toBe(1001); + expect(savedEvent.payload.title.endsWith('…')).toBe(true); + }); + test('Should increment total events count on each processing', async () => { await worker.handle(generateTask()); await worker.handle(generateTask());