Conversation
…d on invalid return
… for validation, ensuring original data remains intact on invalid returns.
There was a problem hiding this comment.
Pull request overview
This PR hardens the beforeSend and beforeBreadcrumb hooks so that invalid hook returns (or mutations of required fields) don’t corrupt the original event/breadcrumb being sent/stored.
Changes:
- Pass a
structuredCloneof the event/breadcrumb intobeforeSend/beforeBreadcrumband only apply results when validation succeeds. - Consolidate the “invalid/no return” cases into a single fallback path with a unified warning message.
- Extend breadcrumb validation by requiring
messageto be a non-empty string, and update/expand tests accordingly.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
src/index.ts |
Clones payload before beforeSend, validates hook result, and uses unified warning on fallback. |
src/modules/breadcrumbs.ts |
Clones breadcrumb before beforeBreadcrumb, validates hook result (including message), and uses unified warning on fallback. |
tests/before-send.test.ts |
Consolidates invalid-return coverage into parameterized tests and adds mutation/required-field deletion cases. |
tests/breadcrumbs.test.ts |
Consolidates invalid-return coverage into parameterized tests and adds mutation/required-field deletion cases. |
package.json |
Bumps package version to 3.3.2. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/index.ts
Outdated
| const eventPayloadClone = structuredClone(payload); | ||
| const result = this.beforeSend(eventPayloadClone); |
There was a problem hiding this comment.
structuredClone(payload) can throw (e.g., DataCloneError) if the payload contains non-cloneable values such as functions, class instances with unserializable internals, etc. Since this call is not wrapped, a user-provided beforeSend + custom context/user data could crash error reporting entirely. Consider wrapping the clone in a try/catch and falling back to calling beforeSend with the original payload (or skipping the hook) while still ensuring the original payload is preserved when validation fails.
| /** | ||
| * Anything else is invalid — warn, payload stays untouched (hook only received a clone) | ||
| */ | ||
| console.warn('[Hawk] Invalid beforeSend value. It should return event or false. Event is sent without changes.'); |
There was a problem hiding this comment.
The warning message says the hook "should return event or false", but the public beforeSend type/documentation explicitly allows returning nothing (void/undefined/null) to keep the original event (with a warning). The current wording is misleading for the undefined/null cases that are treated as an allowed no-op. Update the message to include the "return nothing to keep original" option (and ideally distinguish between "returned nothing" vs "returned invalid value").
src/modules/breadcrumbs.ts
Outdated
| const breadcrumbClone = structuredClone(bc); | ||
| const result = this.options.beforeBreadcrumb(breadcrumbClone, hint); |
There was a problem hiding this comment.
structuredClone(bc) can throw (e.g., DataCloneError) if the breadcrumb contains non-cloneable values (commonly via breadcrumb.data). Since this is unhandled, adding a breadcrumb with such data would throw and prevent breadcrumb storage (and potentially affect subsequent error sending). Consider wrapping the clone in try/catch and falling back to passing the original breadcrumb into the hook (or skipping the hook) while keeping the current "restore original on invalid" behavior where possible.
| /** | ||
| * Anything else is invalid — warn, bc stays untouched (hook only received a clone) | ||
| */ | ||
| console.warn('[Hawk] Invalid beforeBreadcrumb value. It should return breadcrumb or false. Breadcrumb is stored without changes.'); |
There was a problem hiding this comment.
The warning message says the hook "should return breadcrumb or false", but beforeBreadcrumb also supports returning nothing (void/undefined/null) to keep the original breadcrumb (with a warning) per the options docs above. The current wording is misleading for the intentional no-return case; consider updating it to mention that returning nothing keeps the original breadcrumb.
Summary
structuredClonebefore passing tobeforeSend/beforeBreadcrumbhooks, so the original is restored when the hook returns an invalid value or mutates required fieldsmessagefield validation toisValidBreadcrumb(must be a non-empty string), matchingisValidEventPayloadwhich already validatestitle