Skip to content

Netwrok request failed 300426#2344

Open
simo6529 wants to merge 9 commits intomainfrom
netwrok-request-failed-300426
Open

Netwrok request failed 300426#2344
simo6529 wants to merge 9 commits intomainfrom
netwrok-request-failed-300426

Conversation

@simo6529
Copy link
Copy Markdown
Collaborator

@simo6529 simo6529 commented May 4, 2026

Summary by CodeRabbit

  • Bug Fixes

    • Improved detection and classification of network-related errors in error tracking
    • Added intelligent sampling to reduce noise from low-value browser transport network errors
    • Enhanced first-party URL detection for better error attribution
  • Tests

    • Expanded test coverage for network error handling under various sampling conditions
    • Added tests for URL sanitization and first-party API endpoint detection
    • Comprehensive test cases for error filtering and classification logic

Signed-off-by: Simo <simo@6529.io>
Signed-off-by: Simo <simo@6529.io>
Signed-off-by: Simo <simo@6529.io>
Signed-off-by: Simo <simo@6529.io>
Signed-off-by: Simo <simo@6529.io>
Signed-off-by: Simo <simo@6529.io>
Signed-off-by: Simo <simo@6529.io>
Signed-off-by: Simo <simo@6529.io>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 4, 2026

📝 Walkthrough

Walkthrough

This PR implements low-value network error sampling and detection for Sentry error instrumentation. It adds URL extraction from browser network errors and breadcrumbs, first-party API classification logic, a sampling decision system to drop or tag noisy errors, and breadcrumb enrichment with first-party metadata. Core changes span error classification, URL sanitization, and beforeSend hook integration.

Changes

Low-Value Network Error Sampling & Breadcrumb Enrichment

Layer / File(s) Summary
Data Shape
utils/sentry-client-filters.ts
SentryClientEvent extended with optional event_id and message fields; new exported LowValueNetworkErrorDecision type ("not_applicable" | "drop" | "keep_sampled") and LOW_VALUE_NETWORK_ERROR_SAMPLE_RATE constant (0.1).
Breadcrumb Enrichment
utils/sentry-sanitizer.ts
sanitizeSentryBreadcrumb now computes and injects url.is_first_party and url.is_first_party_api metadata when parsing breadcrumb URLs against 6529.io hosts and API path patterns.
URL Extraction & Classification
instrumentation-client.ts, utils/sentry-client-filters.ts
New helper functions extract URLs from error messages (parentheses pattern), HTTP breadcrumbs, or event request fields; classify errors as app-wrapped vs raw browser network errors; detect first-party and first-party API targets via hostname/pathname rules.
Sampling Decision Logic
utils/sentry-client-filters.ts
Exported getLowValueNetworkErrorDecision(...) and tagSampledLowValueNetworkError(...) implement low-value first-party network error filtering: derives candidate URLs from breadcrumbs, applies stable-hash-based sampling against configurable rate, and returns drop/keep decisions.
Instrumentation Integration
instrumentation-client.ts
handleNetworkError refactored to accept generic Error and rewrite messages using extracted breadcrumb URLs; beforeSend hook guards network handling behind error-type checks and invokes low-value decision logic to filter or tag sampled events.
Tests & Validation
__tests__/instrumentation-client.test.ts, __tests__/utils/sentry-client-filters.test.ts, __tests__/utils/sentry-sanitizer.test.ts
New test suites validate breadcrumb URL sanitization, first-party detection, network error classification, sampling decisions across various URL/status/tag combinations, and correct tagging of sampled-in errors.

Sequence Diagram

sequenceDiagram
    participant Browser as Browser/App
    participant Error as Error Handler
    participant Sentry as Sentry SDK
    participant BeforeSend as beforeSend Hook
    participant Breadcrumbs as Breadcrumb System
    participant Decision as Sampling Decision
    participant Transport as Sentry Transport

    Browser->>Error: Network error occurs (fetch fails)
    Error->>Breadcrumbs: HTTP breadcrumb recorded (status 0)
    Error->>Sentry: captureException(error)
    Sentry->>BeforeSend: beforeSend(event)
    
    BeforeSend->>Error: Classify as app-wrapped or raw browser error
    alt Raw Browser Network Error
        Error->>Breadcrumbs: Extract latest failed fetch breadcrumb URL
        Error->>BeforeSend: Rewrite exception message with breadcrumb URL
    else App-Wrapped Error
        Error->>BeforeSend: Preserve original message
    end

    BeforeSend->>Decision: getLowValueNetworkErrorDecision(event)
    Decision->>Decision: Extract URL candidates from breadcrumbs
    Decision->>Decision: Detect first-party vs third-party targets
    Decision->>Decision: Apply stable-hash sampling (10% rate)
    
    alt Sampled Out (Drop)
        Decision-->>BeforeSend: "drop"
        BeforeSend->>Sentry: return null
        Sentry-->>Transport: Event discarded
    else Sampled In (Keep)
        Decision-->>BeforeSend: "keep_sampled"
        BeforeSend->>Error: Tag event with network metadata
        BeforeSend->>Sentry: return event (tagged)
        Sentry->>Transport: Send tagged event
    else Not Applicable (Keep)
        Decision-->>BeforeSend: "not_applicable"
        BeforeSend->>Sentry: return event
        Sentry->>Transport: Send untagged event
    end
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly Related PRs

  • Sentry 2 #1657: Modifies the same utils/sentry-client-filters.ts and shouldFilterFilenameExceptions logic used in instrumentation.
  • Sentry Client config #1628: Alters instrumentation-client.ts beforeSend hook event-filtering behavior.
  • Sentry Issues #1629: Refactors instrumentation-client.ts network-error handling and URL extraction helpers.

Suggested Reviewers

  • prxt6529
  • GelatoGenesis
  • ragnep

Poem

🐰 Network noise falls silent, a sample at a time,
First-party breadcrumbs guide URLs so fine,
Sentry hooks dance with filtering grace,
Low-value errors know their place!
Hopping through logs with precision and care,
Error signals now fresh as spring air.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Title check ⚠️ Warning The title contains a typo ('Netwrok' instead of 'Network') and is vague; it references a ticket number but doesn't clearly describe the main change, which is adding network error sampling logic and breadcrumb sanitization. Correct the typo and use a more descriptive title like 'Add low-value network error sampling and breadcrumb sanitization' to clearly convey the main changes in the pull request.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch netwrok-request-failed-300426

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 0/1 reviews remaining, refill in 60 minutes.

Comment @coderabbitai help to get the list of available commands and usage tips.

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented May 4, 2026

Quality Gate Failed Quality Gate failed

Failed conditions
1 Security Hotspot

See analysis details on SonarQube Cloud

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9b2cf5a1a0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +445 to +446
if (latestBreadcrumb?.statusCode !== 0) {
return false;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Match against latest failed breadcrumb, not latest status

The low-value network filter currently inspects only the single most recent HTTP breadcrumb with any status, and immediately returns when that status is not 0. In events where a failed first-party request (status_code: 0) is followed by a later successful request before capture, this path returns "not_applicable" and the noisy browser transport error is never sampled/dropped. This undermines the new noise-reduction behavior for realistic multi-request pages; the check should walk back to the most recent failed transport breadcrumb (or otherwise consider matching failed breadcrumbs), not bail on the first non-zero status.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@instrumentation-client.ts`:
- Around line 299-303: The current raw-browser check (isRawBrowserNetworkError
using error instanceof TypeError && isNetworkError(error.message)) is too
permissive and can catch unrelated TypeErrors; tighten it so only genuine
network-related TypeErrors are matched before retagging/fingerprinting. Update
the isRawBrowserNetworkError condition (or refine isNetworkError) to require a
stricter match on error.message (e.g., explicit tokens like "NetworkError",
"Failed to fetch", or a regex with word boundaries like /\bnetwork\b/i) and/or
check error.name equals "NetworkError" where available; keep the existing
isAppWrappedApiNetworkError logic intact so you only retag events when either
isAppWrappedApiNetworkError(error.message) is true or the tightened
isRawBrowserNetworkError is true. Ensure references to
isAppWrappedApiNetworkError, isNetworkError, isRawBrowserNetworkError, and the
error instanceof TypeError check are updated accordingly.
- Around line 139-173: The helper getLatestHttpBreadcrumbUrl currently only
treats explicit status_code === 0 as a failed transport; update
getLatestHttpBreadcrumbUrl (or getLatestNetworkBreadcrumbUrl) to apply the same
failed-transport heuristic used by getLowValueNetworkErrorDecision: if an
HTTP/fetch breadcrumb has no explicit status code but has breadcrumb.level ===
"error" (and is identified as a fetch-type breadcrumb by isHttpBreadcrumb or
equivalent), treat it as status 0 for matching so a later successful breadcrumb
cannot overwrite the failed-transport URL; ensure you reference and reuse the
same predicate logic from getLowValueNetworkErrorDecision to keep behavior
consistent.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1efa7d1e-6312-4aec-a37d-d56b564f0f76

📥 Commits

Reviewing files that changed from the base of the PR and between 97e6700 and 9b2cf5a.

📒 Files selected for processing (6)
  • __tests__/instrumentation-client.test.ts
  • __tests__/utils/sentry-client-filters.test.ts
  • __tests__/utils/sentry-sanitizer.test.ts
  • instrumentation-client.ts
  • utils/sentry-client-filters.ts
  • utils/sentry-sanitizer.ts

Comment thread instrumentation-client.ts
Comment on lines +139 to +173
function getLatestHttpBreadcrumbUrl(
event: Sentry.Event,
statusCode?: number
): unknown {
const breadcrumbs = event.breadcrumbs;
if (!Array.isArray(breadcrumbs)) {
return undefined;
}

for (let index = breadcrumbs.length - 1; index >= 0; index -= 1) {
const breadcrumb = breadcrumbs[index];
if (!breadcrumb || !isHttpBreadcrumb(breadcrumb)) {
continue;
}

if (
statusCode !== undefined &&
getBreadcrumbStatusCode(breadcrumb) !== statusCode
) {
continue;
}

const url = breadcrumb.data?.["url"];
if (url) {
return url;
}
}

return undefined;
}

function getLatestNetworkBreadcrumbUrl(event: Sentry.Event): unknown {
return (
getLatestHttpBreadcrumbUrl(event, 0) ?? getLatestHttpBreadcrumbUrl(event)
);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Use the same failed-transport breadcrumb heuristic here as in the sampler.

This helper only treats explicit status_code === 0 as a failed transport. getLowValueNetworkErrorDecision() also treats fetch breadcrumbs with level: "error" and no status as status 0, so a later successful HTTP breadcrumb can rewrite the message with the wrong URL here and make the drop check miss the real failed target.

Proposed fix
 function getBreadcrumbStatusCode(breadcrumb: Breadcrumb): number | null {
   const data = breadcrumb.data;
   return (
     getNumericValue(data?.["status_code"]) ??
     getNumericValue(data?.["http.response.status_code"])
   );
 }
 
+function getBreadcrumbTransportStatusCode(breadcrumb: Breadcrumb): number | null {
+  const statusCode = getBreadcrumbStatusCode(breadcrumb);
+  if (statusCode !== null) {
+    return statusCode;
+  }
+
+  if (breadcrumb.category === "fetch" && breadcrumb.level === "error") {
+    return 0;
+  }
+
+  return null;
+}
+
 function getLatestHttpBreadcrumbUrl(
   event: Sentry.Event,
   statusCode?: number
 ): unknown {
   const breadcrumbs = event.breadcrumbs;
@@
   for (let index = breadcrumbs.length - 1; index >= 0; index -= 1) {
     const breadcrumb = breadcrumbs[index];
     if (!breadcrumb || !isHttpBreadcrumb(breadcrumb)) {
       continue;
     }
 
-    if (
-      statusCode !== undefined &&
-      getBreadcrumbStatusCode(breadcrumb) !== statusCode
-    ) {
+    const breadcrumbStatus =
+      statusCode === 0
+        ? getBreadcrumbTransportStatusCode(breadcrumb)
+        : getBreadcrumbStatusCode(breadcrumb);
+    if (statusCode !== undefined && breadcrumbStatus !== statusCode) {
       continue;
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@instrumentation-client.ts` around lines 139 - 173, The helper
getLatestHttpBreadcrumbUrl currently only treats explicit status_code === 0 as a
failed transport; update getLatestHttpBreadcrumbUrl (or
getLatestNetworkBreadcrumbUrl) to apply the same failed-transport heuristic used
by getLowValueNetworkErrorDecision: if an HTTP/fetch breadcrumb has no explicit
status code but has breadcrumb.level === "error" (and is identified as a
fetch-type breadcrumb by isHttpBreadcrumb or equivalent), treat it as status 0
for matching so a later successful breadcrumb cannot overwrite the
failed-transport URL; ensure you reference and reuse the same predicate logic
from getLowValueNetworkErrorDecision to keep behavior consistent.

Comment thread instrumentation-client.ts
Comment on lines +299 to +303
const isAppWrappedError = isAppWrappedApiNetworkError(error.message);
const isRawBrowserNetworkError =
error instanceof TypeError && isNetworkError(error.message);

if (!isAppWrappedError && !isRawBrowserNetworkError) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Tighten raw browser network detection before retagging the event.

isNetworkError() still matches any message containing the bare word network, so this branch will rewrite, fingerprint, and potentially sample out unrelated TypeErrors whose text just happens to mention that word.

Proposed fix
-  const isRawBrowserNetworkError =
-    error instanceof TypeError && isNetworkError(error.message);
+  const normalizedMessage = error.message.toLowerCase();
+  const isRawBrowserNetworkError =
+    error instanceof TypeError &&
+    (
+      normalizedMessage.includes("failed to fetch") ||
+      normalizedMessage.includes("load failed") ||
+      normalizedMessage.includes("networkerror") ||
+      normalizedMessage.includes("network error") ||
+      normalizedMessage.includes("network request failed")
+    );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@instrumentation-client.ts` around lines 299 - 303, The current raw-browser
check (isRawBrowserNetworkError using error instanceof TypeError &&
isNetworkError(error.message)) is too permissive and can catch unrelated
TypeErrors; tighten it so only genuine network-related TypeErrors are matched
before retagging/fingerprinting. Update the isRawBrowserNetworkError condition
(or refine isNetworkError) to require a stricter match on error.message (e.g.,
explicit tokens like "NetworkError", "Failed to fetch", or a regex with word
boundaries like /\bnetwork\b/i) and/or check error.name equals "NetworkError"
where available; keep the existing isAppWrappedApiNetworkError logic intact so
you only retag events when either isAppWrappedApiNetworkError(error.message) is
true or the tightened isRawBrowserNetworkError is true. Ensure references to
isAppWrappedApiNetworkError, isNetworkError, isRawBrowserNetworkError, and the
error instanceof TypeError check are updated accordingly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant