@@ -2,23 +2,23 @@ import Socket from './modules/socket';
22import Sanitizer from './modules/sanitizer' ;
33import log from './utils/log' ;
44import StackParser from './modules/stackParser' ;
5- import type { CatcherMessage , HawkInitialSettings , BreadcrumbsAPI } from './types' ;
5+ import type { CatcherMessage , HawkInitialSettings , BreadcrumbsAPI , Transport } from './types' ;
66import { VueIntegration } from './integrations/vue' ;
77import { id } from './utils/id' ;
88import type {
99 AffectedUser ,
1010 EventContext ,
1111 JavaScriptAddons ,
1212 VueIntegrationAddons ,
13- Json , EncodedIntegrationToken , DecodedIntegrationToken ,
13+ Json , EncodedIntegrationToken , DecodedIntegrationToken
1414} from '@hawk.so/types' ;
1515import type { JavaScriptCatcherIntegrations } from './types/integrations' ;
1616import { EventRejectedError } from './errors' ;
1717import type { HawkJavaScriptEvent } from './types' ;
1818import { isErrorProcessed , markErrorAsProcessed } from './utils/event' ;
1919import { ConsoleCatcher } from './addons/consoleCatcher' ;
2020import { BreadcrumbManager } from './addons/breadcrumbs' ;
21- import { validateUser , validateContext } from './utils/validation' ;
21+ import { validateUser , validateContext , isValidEventPayload } from './utils/validation' ;
2222
2323/**
2424 * Allow to use global VERSION, that will be overwritten by Webpack
@@ -73,16 +73,18 @@ export default class Catcher {
7373 private context : EventContext | undefined ;
7474
7575 /**
76- * This Method allows developer to filter any data you don't want sending to Hawk
77- * If method returns false, event will not be sent
76+ * This Method allows developer to filter any data you don't want sending to Hawk.
77+ * - Return modified event — it will be sent instead of the original.
78+ * - Return `false` — the event will be dropped entirely.
79+ * - Any other value is invalid — the original event is sent as-is (a warning is logged).
7880 */
79- private readonly beforeSend : undefined | ( ( event : HawkJavaScriptEvent ) => HawkJavaScriptEvent | false ) ;
81+ private readonly beforeSend : undefined | ( ( event : HawkJavaScriptEvent ) => HawkJavaScriptEvent | false | void ) ;
8082
8183 /**
8284 * Transport for dialog between Catcher and Collector
83- * (WebSocket decorator)
85+ * (WebSocket decorator by default, or custom via settings.transport )
8486 */
85- private readonly transport : Socket ;
87+ private readonly transport : Transport ;
8688
8789 /**
8890 * Module for parsing backtrace
@@ -148,7 +150,7 @@ export default class Catcher {
148150 /**
149151 * Init transport
150152 */
151- this . transport = new Socket ( {
153+ this . transport = settings . transport ?? new Socket ( {
152154 collectorEndpoint : settings . collectorEndpoint || `wss://${ this . getIntegrationId ( ) } .k1.hawk.so:443/ws` ,
153155 reconnectionAttempts : settings . reconnectionAttempts ,
154156 reconnectionTimeout : settings . reconnectionTimeout ,
@@ -436,12 +438,29 @@ export default class Catcher {
436438 * Filter sensitive data
437439 */
438440 if ( typeof this . beforeSend === 'function' ) {
439- const beforeSendResult = this . beforeSend ( payload ) ;
441+ const eventPayloadClone = structuredClone ( payload ) ;
442+ const result = this . beforeSend ( eventPayloadClone ) ;
440443
441- if ( beforeSendResult === false ) {
444+ /**
445+ * false → drop event
446+ */
447+ if ( result === false ) {
442448 throw new EventRejectedError ( 'Event rejected by beforeSend method.' ) ;
449+ }
450+
451+ /**
452+ * Valid event payload → use it instead of original
453+ */
454+ if ( isValidEventPayload ( result ) ) {
455+ payload = result as HawkJavaScriptEvent ;
443456 } else {
444- payload = beforeSendResult ;
457+ /**
458+ * Anything else is invalid — warn, payload stays untouched (hook only received a clone)
459+ */
460+ log (
461+ 'Invalid beforeSend value. It should return event or false. Event is sent without changes.' ,
462+ 'warn'
463+ ) ;
445464 }
446465 }
447466
0 commit comments