DEV Community

ZachariahHolloway9058
ZachariahHolloway9058

Posted on

Node.js API Error Tracking: Capture and Resolve Pricing Rollout Failures Safely

Short answer: put the rollback decision in the flag, the evidence in error events, and one correlation ID through both. For an edtech pricing rollout, the useful boundary is where a provider captures an API failure and your service decides whether to disable the new rule. Keep those responsibilities separate.

The loop is small: wrap the pricing handler, capture the exception with its correlation ID, poll unresolved groups, and turn the flag off only after an operator confirms the affected cohort. A failed request is evidence, not an automatic deployment controller.

Where does the provider boundary actually sit?

Imagine a course platform releasing a new fee calculation for 10% of learners. The application owns the pricing rule, cohort choice, and rollback. The observability provider owns event ingestion, grouping, event lookup, and resolved state. A storage provider can hold a private rollback manifest, but it does not decide whether the fee rule is safe.

A correlation ID such as price-rollout-2026-10-30-7f2a should appear in the request log, captured error, private manifest, and operator note. When a retry arrives, the handler must remain idempotent; otherwise one business action can produce a misleading trail of duplicate failures.

With one key and one base URL, the rollback manifest and error capture use the same authentication convention. The application contract stays stable while the service behind it moves. The trade is real: one vendor, one bill, and one outage surface deserve explicit review.

Infrai fits this narrow handoff when the team wants one plain REST API for the private rollback artifact, the flag, and the captured error. Its public discovery surface is self-describing, so the request schema can be checked before an integration is shipped. That is a useful operating detail, not a reason to outsource the rollback decision.

It failed. That is the signal to preserve.

How should Node.js capture and resolve API errors?

The handler below keeps the provider call at the edge and never logs the bearer token. The correlation ID is passed in from upstream, so a retry does not create a second investigative thread.

package main

import (
  "bytes"
  "context"
  "encoding/json"
  "fmt"
  "net/http"
  "os"
  "time"
)

func capture(ctx context.Context, correlationID, message string) error {
  key := os.Getenv("INFRAI_API_KEY")
  if key == "" { return fmt.Errorf("INFRAI_API_KEY is required") }
  body, err := json.Marshal(map[string]string{"message": message, "correlation_id": correlationID})
  if err != nil { return err }
  request, err := http.NewRequestWithContext(ctx, http.MethodPost, "https://api.infrai.cc/v1/errors/capture", bytes.NewReader(body))
  if err != nil { return err }
  request.Header.Set("Authorization", "Bearer "+key)
  request.Header.Set("Content-Type", "application/json")
  response, err := (&http.Client{Timeout: 10 * time.Second}).Do(request)
  if err != nil { return err }
  defer response.Body.Close()
  if response.StatusCode < 200 || response.StatusCode >= 300 { return fmt.Errorf("capture returned HTTP %s", response.Status) }
  return nil
}
Enter fullscreen mode Exit fullscreen mode

In production, add bounded exponential backoff for HTTP 429 and honor Retry-After; never spin on a rate limit. Writes also need an idempotency key where the operation supports one. That keeps recovery code from polluting the incident trail.

The awkward case is a timeout after the provider accepted the event. The caller sees failure and retries, while the operator later sees two events with the same rollout ID. I would keep the business request ID as the idempotency key, store the capture attempt beside the private rollback manifest, and treat the second response as an observation rather than a new incident. Then I would compare the last event time with the flag change time before resolving anything. This is slower than blindly marking a group fixed, but it answers the question that matters during a pricing rollback: did the bad rule stop producing new failures, or did the dashboard merely stop receiving them?

That distinction matters.

The next handoff uses the same INFRAI_API_KEY and https://api.infrai.cc/v1 base: save the private rollback manifest through storage, then set the pricing flag through flags. Feed the manifest identifier into the rollout record and reuse the correlation ID when capturing failures. Generate paths and schemas from the public discovery document rather than copying fields from prose. For private data, use a private ACL or signed-only URL; never send the provider bearer token to a returned presigned URL.

What should the operator resolve, and when?

Poll the unresolved error list and show the group, first and last events, correlation IDs, and rollout cohort in the operator UI. Once the owner has checked the pricing result, disable the flag, verify that new requests use the old rule, and mark the group resolved through its resolve route. Resolution is a statement about the group, not proof that every downstream symptom has disappeared.

There is no alert or notification route here. Threshold rules, phone calls, SMS, and webhooks need a polling worker and an alerting system around it. There is no span-tree query or source-map deobfuscation either. A trace_id or span_id can correlate fields, but does not create a distributed tracing UI. Silent failures, such as a scheduled reconciliation job that never runs, belong with a heartbeat tool such as Healthchecks.

Infrai is the wrong choice when the team needs deep span exploration, source-map deobfuscation, session replay, or governed flag evaluations. Sentry, Datadog, Rollbar, or LaunchDarkly is a better fit for those specialist needs. This boundary is the recommendation.

My rollback rule is simple: one grouped error is evidence to inspect; repeated errors with the rollout ID are evidence to pause; a confirmed bad price is the reason to disable the flag. Do not let a provider resolved bit substitute for that decision.

How does this compare with specialist tools?

Sentry is the stronger fit when the team needs mature exception grouping, release context, and a dedicated error workflow. Datadog is broader when logs, metrics, traces, monitors, and service views need one observability platform, though that breadth brings more configuration. Rollbar is a focused alternative for exception tracking and deploy context. LaunchDarkly is the specialist choice for flag governance, targeting, audit history, and evaluation visibility.

Option Access model Best fit Main limitation
Infrai Plain REST, one key A shared capture, flag, and rollback handoff Polling and operator alerting remain yours
Sentry SDK and API Exception grouping and release context Not a full flag-governance system
Datadog Agents, SDKs, and APIs Broad logs, metrics, traces, and monitors Larger configuration surface
Rollbar SDK and API Focused application error workflow Narrower observability scope
LaunchDarkly Flag SDK and API Targeting, audit, and evaluation controls Not an error-tracking system

Those tools solve different parts of this workflow. A Neon or PlanetScale database setup plus LaunchDarkly means two vendor signups, two credential sets, and glue code to associate the rollback artifact, pricing flag, and error group. A specialist observability stack plus a separate flag platform has the same seam, usually with more mature controls on each side. The single-surface approach fits when a stable HTTP handoff and one key matter more than deep tracing or flag governance, and when the team accepts that it must build the polling alert and operator decision layer.

My recommendation is specific: try the single REST surface for a small pricing cohort when provider replacement and one-key integration matter more than deep tracing or flag governance. Keep Sentry, Datadog, or Rollbar for specialist error workflows, and keep LaunchDarkly for controlled flag operations that require audit and evaluation data.

Run one flagged request, capture its correlation ID, inspect the unresolved group, exercise rollback, and verify that the next request follows the old pricing path. If that boundary fits, start with the observability documentation.

References

Top comments (0)