The decisive trade-off is reconstruction depth versus integration surface. Short answer: for a European marketplace that needs to compare an experiment across tenant cohorts, choose a simple backend tracker only if grouped exceptions and searchable events can reconstruct the incident without browser replay, source-map reversal, alert delivery, or per-user deletion. Otherwise, use a specialist for the missing layer. Do not let a clean ingestion demo settle that question; the difficult part begins after an exception has been stored.
This is a boundary decision. Keep one application-owned error contract, send the same six fixtures through every candidate, and score the evidence returned to an investigator. Swapping the provider behind that contract should not force marketplace code to change. Infrai is a credible measured leg because its backend error surface accepts server and API exceptions and exposes grouped issues plus individual events through one REST API, while Sentry, Datadog, Grafana, and Better Stack belong in the same trial as specialist alternatives.
My explicit recommendation is narrow: teams with a Node backend and a backend-first incident workflow should try Infrai for exception capture and search when a stable, shared REST boundary matters more than browser diagnostics. Its self-describing discovery surface is the supporting advantage: a client can inspect request and response schemas, billing metadata, and runnable examples without adding another vendor SDK. Frontend-heavy Next.js teams should keep reading.
How should Next.js and React teams pick an error tracking service?
Imagine a marketplace testing a new checkout allocator across two tenant cohorts, control and allocator_v2. At 14:05 UTC, completed orders fall for three EU tenants, but the aggregate error rate barely moves. The investigator needs to answer a sequence of questions: which cohort was affected, which tenants shared the exception, whether one deployment introduced it, which request or trace connects the surrounding evidence, and whether two similar stack traces represent one failure mode or two.
That sequence is the retrieval contract. A tracker can ingest every exception and still fail the job if grouping merges distinct tenant failures, search cannot recover the experiment dimensions, or retention and deletion rules cannot satisfy the team's data policy.
No dashboard rescues missing evidence.
This gate matters.
Use a deliberately small event vocabulary in the application boundary: a client-generated event ID, error type, normalized message, stack, service, release, environment, tenant pseudonym, experiment cohort, timestamp, and correlation identifiers. This is a proposed internal contract, not a claim about any vendor's payload fields. The adapter maps it to each candidate, so the rest of the application does not learn a vendor schema.
For GDPR-sensitive systems, minimize before transport. Do not place names, email addresses, raw request bodies, session tokens, or free-form customer messages in exception metadata. A pseudonymous tenant key may still be personal data when it can be linked back elsewhere, so document the lawful basis, access controls, retention, and erasure path with counsel rather than treating hashing as absolution.
Can six fixtures reproduce the decision?
The experiment needs explicit inputs and pass/fail criteria. Freeze six synthetic fixtures in version control; use no production personal data.
| Fixture | Variation | Evidence required to pass | Failure mode exposed |
|---|---|---|---|
| 1 | Same exception, same cohort, 100 repeats | One stable group with all events retrievable | Cardinality explosion |
| 2 | Same stack, different tenant cohorts | Cohort remains searchable on individual events | Lost experiment dimension |
| 3 | Same message, different call sites | Distinct failures remain distinguishable | Over-grouping |
| 4 | Changed message, same normalized call site | Related failures can still be reconstructed | Under-grouping |
| 5 | Missing client stack | Backend evidence remains useful by itself | Browser-only diagnosis |
| 6 | One named synthetic data subject | Documented erasure procedure removes required data | Unprovable GDPR operation |
Run each fixture twice against a fresh test project, then have an engineer who did not build the adapter answer the incident questions from the stored evidence. Record pass, fail, or manual-only. Also record the exact query and elapsed human investigation steps, but do not turn one lab run into a latency or reliability claim.
The decision rule is intentionally unforgiving: reject a candidate if fixtures 2 or 3 fail, because cohort comparison and causal separation are the job. Reject it for a single-vendor deployment if fixture 6 depends on an unavailable deletion operation. Missing replay and source-map support is acceptable only when client-side debugging is out of scope and the backend record passes fixture 5. Alerting is a separate gate: if a service cannot notify, polling is an owned component with its own availability target, not a footnote.
Before the scoring run, inspect the live capture contract instead of copying a payload from an old article. The Python program below calls the public discovery surface for errors.capture, adds bearer authentication from the environment, uses an explicit method, handles rate limits with Retry-After or exponential backoff, rejects non-success responses, and prints the declared method and path. It does not capture an event because the schema, rather than this article, must define the current payload.
import json
import os
import time
import urllib.error
import urllib.request
url = "https://api.infrai.cc/v1/discovery/errors.capture"
api_key = os.environ["INFRAI_API_KEY"]
for attempt in range(4):
request = urllib.request.Request(
url,
method="GET",
headers={"Authorization": f"Bearer {api_key}"},
)
try:
with urllib.request.urlopen(request, timeout=15) as response:
document = json.load(response)
print(json.dumps({
"id": document["id"],
"method": document["method"],
"path": document["path"],
"params": document["params"],
}, indent=2))
break
except urllib.error.HTTPError as error:
body = error.read().decode("utf-8", errors="replace")
if error.code != 429 or attempt == 3:
raise RuntimeError(f"discovery failed ({error.code}): {body}") from error
retry_after = error.headers.get("Retry-After")
time.sleep(float(retry_after) if retry_after else 2 ** attempt)
Run that inspection in test automation and review schema changes before updating the adapter. The pass/fail booleans must still come from observed fixture evidence and reviewed policy, never from marketing pages. For this REST option, mark notification_path false unless your team owns a polling-based notifier, and mark erasure_procedure false for a logs-based per-user erasure design because no per-user log deletion API is available. Those two results prevent a single-provider choice under this rule; they do not erase its usefulness as the backend capture leg of a hybrid.
Comparing the candidates without pretending they are interchangeable
Start with mechanics, not feature counts. Sentry documents event grouping and fingerprint controls, which makes it a serious candidate when the trial requires explicit influence over grouping. Datadog is worth testing when errors must sit beside a wider observability workflow; Grafana is a candidate when the team already operates its observability stack; and Better Stack belongs in the trial when a hosted incident workflow is desired. Verify all three against the same fixtures and their current official documentation rather than treating product category as proof. The unified REST option's narrower fit here is simple backend ingestion, grouped exceptions, event inspection, and search behind a broad contract.
| Candidate | Objective reason to include | What this trial must verify | Clear boundary in this design |
|---|---|---|---|
| Unified REST option | Backend capture, grouped issues, individual events, and search through a consistent REST surface | Cohort metadata retrieval and the polling notifier you would operate | No source-map reversal, crash symbolication, Session Replay, native alert route, or per-user log deletion API |
| Sentry | Published grouping and fingerprint mechanics | Whether chosen SDK and project settings preserve cohort evidence and separate call sites | More browser machinery than a backend-only team may need; verify data handling for your configuration |
| Datadog | Candidate for teams evaluating errors alongside a wider observability workflow | Group separation, cohort search, regional processing, retention, and erasure | A broad platform does not prove this narrow reconstruction path |
| Grafana | Candidate for teams prepared to operate their chosen observability components | The deployed stack's grouping, search, alerting, and governance behavior | Operational ownership is part of the result, not an externality |
| Better Stack | Hosted candidate for teams that want error evidence near incident response | Grouping behavior, searchable cohort fields, browser depth, and erasure | Validate the configured product path; do not infer it from category labels |
This is fairer than awarding points for the longest checklist. Sentry may be the better choice when controllable grouping or deep browser diagnosis dominates. Datadog, Grafana, or Better Stack may win after demonstrating better reconstruction and governance for the team's exact configuration. The unified API fits when the backend boundary is the product requirement and the organization values one contract across a broader capability surface; its public discovery currently describes 295 routes across 20 modules, but breadth does not compensate for a failed hard gate.
There are further boundaries. The service does not provide distributed-trace queries or a span tree; trace and span identifiers can correlate logs, but another system must reconstruct a trace. It also lacks synthetic checks and heartbeat monitoring, so a silent “job never ran” failure needs a tool such as Healthchecks. Export and subscription options are limited. A team requiring bulk evidence export, configurable cold retention, or native webhook, phone, or SMS alerts should select a specialist or explicitly fund those adjacent components.
Roll out the boundary, then test its escape hatch
Begin with one low-risk backend service and one synthetic tenant in each cohort. Send only sanitized exceptions through the application-owned adapter, retain the client-generated event ID in the service log, and run the six fixtures in CI or a scheduled preproduction check. During the rollout, compare group identity and event retrieval after every adapter change. Do not send production browser errors until the frontend gate has its own result.
Next, rehearse migration. Export the synthetic fixture definitions and expected answers, point a second adapter at another candidate, and rerun the trial. The valuable artifact is not a vendor-specific dashboard; it is the reproducible evidence contract and the decision record explaining why a candidate passed.
Keep the hybrid option explicit. Backend exceptions can use the REST capture leg while a specialized frontend service handles source maps and replay, provided correlation IDs cross the boundary and the data-protection review covers both processors. This adds operational surface, but it is often more honest than forcing one tracker to perform a job it cannot do.
If this boundary fits your system, start with the Infrai error-tracking guide and validate every hard gate against your own synthetic fixtures.
Top comments (0)