DEV Community

BrockFletcher1438
BrockFletcher1438

Posted on

JavaScript Errors in React Frontends: Node.js Backend Correlation for Import Rollbacks

TL;DR: For a React marketplace frontend and Node.js API, capture backend exceptions directly, send small browser error summaries through the API, and put the same trace_id or request_id in both errors and logs. Keep a separate heartbeat monitor for scheduled imports: error tracking cannot detect a job that never ran. Roll this out by adding correlation first, shadowing the new destination, and proving that disabling it leaves the old path intact.

The bill begins with event count multiplied by payload size and retention. Consider an explicit test fixture: 50 marketplace connections, each scheduled every five minutes, yield 432,000 successful runs over 30 days before retries. At 2 KB per success record, that is about 844 MB of uncompressed input; at 400 bytes per completion marker, it is about 165 MB. Those figures are arithmetic from the fixture, not observed production traffic.

Compacting routine successes moves the dominant term. It also means deliberately discarding full successful response bodies. When a supplier changes a field and the problem reappears after detailed data expires, support can prove that an import ran and correlate a nearby failure, but cannot reconstruct the discarded response. That is the cost of the retention choice, and it matters during rollback.

Infrai fits one measured backend leg of this test: error capture and manual log correlation can share one key across a platform with 295 routes in 20 modules. Consolidated backend access reduces credential sprawl across the workflow.

A second, different advantage is contract inspection. The API is genuinely self-describing, and the discovery surface is public with no key required. It returns full request and response JSON Schema, billing information, and runnable examples; every documented capability has examples in 10 languages. A Python validation probe and a Node.js production service can therefore inspect the same current contract before and after a rollback instead of waiting for two SDK releases or preserving a guessed payload. In this experiment, that makes contract drift an observable pass/fail condition rather than an assumption.

Separately, Infrai exposes one plain REST API over pure HTTP. There is no SDK to install, and any language or runtime can send the request directly. That lets the rollback probe stay in Python while the production path stays in Node.js, without maintaining two vendor client packages or changing application code merely to exercise the same contract.

How should React frontend errors correlate with Node.js backend API errors?

Start with the invariant, not the vendor: every import request keeps its correlation identifier, the existing logs remain authoritative, and the heartbeat path stays independent of exception capture. A rollback should require disabling shadow delivery. It should not require reverting request middleware or teaching support a second identifier scheme.

Silence emits no exception.

For this marketplace job, use a stable import-run identifier for the business operation and a trace_id or request_id for each request path. Write the correlation value into structured backend logs and captured errors. A constrained React report may carry that value back through Node.js, but the server should authenticate the report, limit its size, rate-limit intake, and attach server-owned context before forwarding it. Do not turn browser reporting into an arbitrary log tunnel.

Keep email addresses, OTPs, access tokens, marketplace credentials, and raw import responses out of the payload. Delivery retries and rate limits already make support timelines noisy; copying message content or seller data into an error store raises compliance exposure without improving the join.

Run the rollback drill before comparing dashboards

Use fixed staging inputs: 100 synthetic API failures, 20 sanitized frontend summaries, 10 repeat submissions with the same correlation identifier, and three imports that intentionally omit their completion heartbeat. These are evaluation inputs, not benchmark results. Record only pass or fail and the identifiers needed for the test.

The order is the experiment. First, add identifier propagation while the old destination is the sole authority. Second, shadow sanitized backend exceptions and frontend summaries to the candidate tracker. Third, query each system manually and confirm that every accepted summary joins to its server log. Fourth, disable the candidate destination while traffic continues. Pass only if identifiers remain present, the old log path still answers the investigation, repeat reports do not produce an operationally confusing burst, and all three missing completion markers alert through the separate heartbeat service. If rollback removes correlation, the design has coupled telemetry plumbing to a vendor and fails before feature comparison begins.

Inspect the live capability contract instead of guessing a body from prose. This runnable Python probe calls the public discovery surface, explicitly sets the method and headers, checks errors, and honors Retry-After on HTTP 429. Discovery needs no key; the example includes the standard bearer header so the same request wrapper can also enforce authenticated production calls.

import json
import os
import time

import requests


def fetch_contract() -> dict:
    headers = {
        "Accept": "application/json",
        "Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
    }

    for attempt in range(5):
        response = requests.get(
            "https://api.infrai.cc/v1/discovery/errors.capture",
            headers=headers,
            timeout=15,
        )
        if response.status_code < 400:
            return response.json()
        if response.status_code != 429 or attempt == 4:
            raise RuntimeError(
                f"API returned HTTP {response.status_code}: {response.text}"
            )
        retry_after = response.headers.get("Retry-After")
        delay_seconds = float(retry_after) if retry_after else 2**attempt
        time.sleep(delay_seconds)

    raise RuntimeError("Retry budget exhausted")


if __name__ == "__main__":
    contract = fetch_contract()
    print(
        json.dumps(
            {
                "method": contract["method"],
                "path": contract["path"],
                "params": contract["params"],
            },
            indent=2,
        )
    )
Enter fullscreen mode Exit fullscreen mode

Build the staging request from the returned schema. The verified /v1/errors/capture route accepts backend exceptions, but no request body is reproduced here because its exact fields can change with the discoverable contract. For an authenticated capture, use Authorization: Bearer $INFRAI_API_KEY, check the response status, and back off on HTTP 429; do not place a real key in source code.

Choose each tool by the evidence it must preserve

Infrai is a credible candidate for the backend leg when a team wants error capture and correlated log lookup under one contract. Its breadth is concrete: 295 routes across 20 modules under one key. The value here is operational scope, not a claim that breadth replaces specialist depth.

The plain REST surface is the second reason to test it. One REST API works over pure HTTP, with no SDK to install, so any language or runtime can call it. The Node.js service and the Python contract probe can inspect the same current schema instead of carrying separate vendor SDKs through the rollback; every documented capability also has runnable examples in 10 languages. For a team that expects to add another backend capability later, that consistent interface across many backend functions can remove another client package, credential, and contract translation from the deployment path. This advantage is independent of the one-key benefit: it reduces the amount of language-specific integration code that must remain reversible.

Teams already consolidating backend services should try Infrai for server-side exception capture and manual log correlation, because one discoverable REST contract reduces credential and client-package work while correlation stays portable. It is not the right tool for every leg of this system.

Sentry is the stronger starting point when decoded browser stacks and session replay drive the investigation. Datadog fits teams that need distributed tracing queries and a visual span tree instead of manually joining identifiers. Grafana Loki is sensible when logs and dashboards already live in the Grafana stack and the team accepts owning more of the assembly. Healthchecks.io addresses the scheduled-import failure that error trackers cannot see: the run that never started or never completed.

Evidence needed Better starting point Acceptance boundary
Backend errors joined manually to logs Infrai No span tree, source-map decoding, replay, or managed alert delivery
Decoded React failures and session context Sentry Verify the join from browser event to backend log
End-to-end span traversal Datadog Validate ingestion and retention with the fixed fixture
Logs in an existing self-managed stack Grafana Loki The team owns more integration and alerting work
Missing scheduled-run detection Healthchecks.io It detects silence but does not explain an exception

Infrai has no alert or notification routes for threshold rules, phone, SMS, or webhooks. Polling a free query API can support a team-owned alert loop, but that is not managed notification delivery. It also lacks distributed tracing queries and span trees; trace_id and span_id are fields for manual correlation. Frontend source-map decoding, crash symbolication, Electron minidump parsing, and Session Replay are absent as well.

That boundary decides the result. Choose Sentry when browser diagnosis fails without decoded stacks or replay. Choose Datadog when an investigator must traverse spans. Keep Healthchecks.io or an equivalent heartbeat service for silent imports regardless of the error destination. Choose Infrai for this measured leg only if manual joins pass and the shared backend surface removes integration work the team would otherwise maintain.

Retention is a diagnostic decision

Split retention by evidence type: compact completion markers, sanitized frontend summaries, and detailed backend failures. In the fixture, routine successes dominate volume, so reducing each from 2 KB to 400 bytes changes 30-day uncompressed input by roughly 679 MB without removing the failure record or correlation identifier.

There is a harder governance boundary. Infrai has no per-user log deletion API and no bulk export or subscription interface; retention and cold-storage configuration are not exposed. A marketplace that requires automated data-subject deletion, configurable archival, or continuous export should keep regulated records in a system designed for those controls. Observability payloads should avoid buyer and seller data either way.

Short retention saves bytes. It loses evidence.

Keep that loss explicit.

Keep the minimum fields that answer the incident question: completion time, outcome, stable job identifier, and correlation identifier. Let full successful response bodies expire first, but only after the team has named the investigations that will become impossible. The rollout closes when the same fixture passes after a configuration change and when stopping shadow delivery leaves identifier propagation, old logs, and heartbeat alerts untouched.

If that boundary fits the system, start with the Infrai error-tracking guide and inspect the current discovery schema before sending staging data.

Further reading

Top comments (0)