Skip to content

Commit 1a415bb

Browse files
committed
Protect beforeSend/beforeBreadcrumb hooks with structuredClone
1 parent a2e0c40 commit 1a415bb

File tree

3 files changed

+26
-5
lines changed

3 files changed

+26
-5
lines changed

packages/javascript/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@hawk.so/javascript",
3-
"version": "3.2.16",
3+
"version": "3.2.17",
44
"description": "JavaScript errors tracking for Hawk.so",
55
"files": [
66
"dist"

packages/javascript/src/addons/breadcrumbs.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,7 @@ export interface BreadcrumbsOptions {
5252
* Hook called before each breadcrumb is stored.
5353
* - Return modified breadcrumb — it will be stored instead of the original.
5454
* - Return `false` — the breadcrumb will be discarded.
55-
* - Return nothing (`void` / `undefined` / `null`) — the original breadcrumb is stored as-is (a warning is logged).
56-
* - If the hook returns an invalid value, a warning is logged and the original breadcrumb is stored.
55+
* - Any other value is invalid — the original breadcrumb is stored as-is (a warning is logged).
5756
*/
5857
beforeBreadcrumb?: (breadcrumb: Breadcrumb, hint?: BreadcrumbHint) => Breadcrumb | false | void;
5958

@@ -236,7 +235,18 @@ export class BreadcrumbManager {
236235
* Apply beforeBreadcrumb hook
237236
*/
238237
if (this.options.beforeBreadcrumb) {
239-
const breadcrumbClone = structuredClone(bc);
238+
let breadcrumbClone: Breadcrumb;
239+
240+
try {
241+
breadcrumbClone = structuredClone(bc);
242+
} catch {
243+
/**
244+
* structuredClone may fail on non-cloneable values in breadcrumb.data
245+
* Fall back to passing the original — hook may mutate it, but breadcrumb storage won't crash
246+
*/
247+
breadcrumbClone = bc;
248+
}
249+
240250
const result = this.options.beforeBreadcrumb(breadcrumbClone, hint);
241251

242252
/**

packages/javascript/src/catcher.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,18 @@ export default class Catcher {
438438
* Filter sensitive data
439439
*/
440440
if (typeof this.beforeSend === 'function') {
441-
const eventPayloadClone = structuredClone(payload);
441+
let eventPayloadClone: HawkJavaScriptEvent;
442+
443+
try {
444+
eventPayloadClone = structuredClone(payload);
445+
} catch {
446+
/**
447+
* structuredClone may fail on non-cloneable values (functions, DOM nodes, etc.)
448+
* Fall back to passing the original — hook may mutate it, but at least reporting won't crash
449+
*/
450+
eventPayloadClone = payload;
451+
}
452+
442453
const result = this.beforeSend(eventPayloadClone);
443454

444455
/**

0 commit comments

Comments
 (0)