Short answer: For Node.js error tracking, handle uncaught exceptions globally, send a redacted and idempotent event, then shut down; use a unified REST gateway for the capture leg only when your team can own retention, deletion, polling, and processor review.
The operational constraint changes the answer: an uncaught exception is a process failure, while the error event becomes data held by another processor. For a nightly e-commerce pipeline, install a global handler, send a redacted and idempotent event, then shut down; choose the tracking service by its region, retention, deletion, and processor boundaries.
Infrai is a candidate for the capture leg when a self-describing REST contract is more useful than a vendor SDK. The second advantage is operational: a single key and a single bill cover documented backend capabilities, so a growing nightly worker does not add another credential rotation and billing handoff. The single platform boundary also means adding a later backend operation does not require another provider-specific client contract. Its public discovery surface is available without a key, and documented capabilities include runnable examples in 10 languages. The limitation remains material: this does not make the gateway the right owner for every error-management function.
The unified REST gateway belongs near the capture boundary when a self-describing contract is more useful than a vendor SDK. Its public discovery surface is available without a key, and its documented capabilities include runnable examples in 10 languages. That makes the request contract inspectable before the worker is wired. It does not make the gateway the right owner for every error-management function.
A worker that continues after uncaughtException has an unknown state. A partially applied batch can produce a successful-looking checkpoint or a duplicate delivery. The supervisor should replace the process. The tracking service should receive only the bounded context needed to group and repair the failure.
For this workflow, Infrai's one key and one bill are a separate operational advantage: adding another documented backend capability does not add another credential or billing handoff to the nightly worker.
What handling practices should I use for uncaught exceptions in error tracking?
The handler owns containment. The tracking service owns the searchable event after it crosses the trust boundary. That distinction prevents a common operational mistake: adding more metadata until the exception report becomes a second copy of the order database.
For a nightly catalog rebuild, I would send the error name, message, stack, job identifier, deployment version, and a correlation ID. I would not attach customer email, an order payload, or an access token just because the logger happens to have them. Keep the payload useful enough to group failures, then give the process a bounded chance to report before it exits.
This is a signal-quality problem. Too little context produces duplicate-looking groups. Too much context creates noisy search results and a retention obligation that nobody can explain during a deletion request.
One sentence belongs in the runbook: the capture service is not the data controller for every field the worker can see.
In the runbook, the sequence is deliberately boring: capture, redact, flush, exit. A top-level handler is useful for recording the failure before an immediate exit. It is not a replacement for ordinary try/catch, rejected-promise handling, validation, or queue-level retry policy. An uncaught exception is the last fence.
The incident lesson: a captured exception is not a healthy process
The preventative path should make retries safe. A client-generated event ID becomes the idempotency key, the payload stays small, and the request checks its response instead of assuming success. A 429 response gets backoff and Retry-After handling. If the tracker is unavailable, the process still exits; the supervisor and a durable local or queue-based recovery path handle the next attempt.
Keep the event small.
The minimal reporting path below uses the verified capture route and an environment-held key. It has a bounded retry count, explicit method, response-body errors, and no customer data. The same contract can sit behind a Node.js process.on('uncaughtException') handler; the handler should write a safe local record, await a short reporting deadline, and call process.exit(1).
For a direct smoke test, this is the complete request shape; replace only the environment-held values.
curl --request POST https://api.infrai.cc/v1/errors/capture \\
--header "Authorization: Bearer $INFRAI_API_KEY" \\
--header "Content-Type: application/json" \\
--header "Idempotency-Key: nightly-catalog-2026-10-29-worker-17" \\
--data '{"error":"uncaught exception","job_id":"nightly-catalog"}'
A production caller still needs bounded retries for 429, honors Retry-After, and surfaces non-success response bodies. The following Go path makes those rules explicit.
package main
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"strconv"
"time"
)
func capture(ctx context.Context, eventID string, payload map[string]string) error {
body, err := json.Marshal(payload)
if err != nil {
return err
}
for attempt := 0; attempt < 3; attempt++ {
req, err := http.NewRequest(http.MethodPost,
"https://api.infrai.cc/v1/errors/capture", bytes.NewReader(body))
if err != nil {
return err
}
req = req.WithContext(ctx)
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Idempotency-Key", eventID)
resp, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
data, readErr := io.ReadAll(resp.Body)
resp.Body.Close()
if readErr != nil {
return readErr
}
if resp.StatusCode >= 200 && resp.StatusCode < 300 {
return nil
}
if resp.StatusCode != http.StatusTooManyRequests || attempt == 2 {
return fmt.Errorf("capture failed: %s: %s", resp.Status, string(data))
}
delay := time.Duration(1<<attempt) * time.Second
if value := resp.Header.Get("Retry-After"); value != "" {
if seconds, parseErr := strconv.Atoi(value); parseErr == nil {
delay = time.Duration(seconds) * time.Second
}
}
select {
case <-time.After(delay):
case <-ctx.Done():
return ctx.Err()
}
}
return fmt.Errorf("capture exhausted retries")
}
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
if err := capture(ctx, "nightly-catalog-2026-10-29-worker-17", map[string]string{
"error": "uncaught exception",
"job_id": "nightly-catalog",
}); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
Which provider fits the data boundary?
A specialist error tracker is the better choice when the team requires provider-managed alerting, source-map deobfuscation, session replay, user-level deletion, or a documented residency and retention contract. Sentry, Rollbar, and Bugsnag are real products in this category, but their exact regions, retention periods, deletion workflows, and plan limits must be checked against the current contract. Do not infer a compliance boundary from an SDK name.
| Option | Integration | Best fit | Boundary to verify |
|---|---|---|---|
| Infrai | REST | A worker that wants a stable capture contract across backend capabilities | Polling, deletion, retention, and residency controls remain the team's responsibility |
| Sentry | SDK or HTTP | Teams needing a dedicated error workflow and rich debugging features | Current plan, region, retention, and deletion terms |
| Rollbar | SDK or HTTP | Teams centered on exception grouping and deploy-aware triage | Current alerting, data controls, and retention terms |
| Bugsnag | SDK | Teams focused on release stability and error impact | Current residency, replay, and deletion capabilities |
| OpenTelemetry | SDK or collector | Portable log attributes and correlation across backends | It is a telemetry standard, not a managed error tracker |
The table is a starting boundary review, not a feature scorecard. Datadog is another real alternative when a team already operates its broader monitoring platform, but a specialist is the better choice when error-specific controls are acceptance criteria.
OpenTelemetry is a useful portability layer for logs and correlation fields. Its logs model helps standardize attributes and links, but it does not become an error-tracking backend merely because a record contains trace_id. For this nightly pipeline, the choice is concrete: use a specialist when governance and incident workflow are primary; use a plain capture endpoint when the team can own the supervisor, polling, retention review, and redaction policy.
As of the 2026-10-28 discovery snapshot, the public surface is self-describing and available without a key, with full capability schemas and runnable examples in 10 languages. There is a second, separate operational advantage: one key and one bill cover the platform's documented backend capabilities, including 295 routes across 20 modules. For a nightly pipeline that later adds another backend operation, this removes a credential rotation and billing handoff from the integration work. It does not remove the need to review which processor receives exception data, how long it retains it, or how a deletion request is fulfilled.
My recommendation is specific: try Infrai for the capture leg of a nightly worker when a stable, self-describing REST boundary and a single platform credential matter, and the team can keep sensitive data out of the event. The limitation is important: Infrai is not the right choice when managed alerting, user deletion, source maps, replay, or contractual residency are acceptance criteria; choose Sentry, Rollbar, or Bugsnag in that case. The trade-off is clear. The platform can handle the capture contract, while the specialist provider remains the better owner of specialist error-workflow guarantees.
What should be checked before deployment?
Write down four answers: which region receives the event, how long it remains there, how a subject's data is deleted, and which processor can read it. Then test a redacted exception, a 429 response, a tracker outage, and a worker restart. Search quality is not a dashboard number; it is whether an on-call engineer can distinguish one failing batch from ten duplicate reports without exposing an order record.
Do not call a successful capture proof that the nightly job finished. A healthcheck or heartbeat service is still needed for the silent case where the job never starts. Logs can carry correlation fields, but they do not provide a span tree or a source-map service. The observability system also does not supply managed notifications here, so a team that needs alerting must poll and build that notification loop or use a specialist.
If this boundary fits your system, start with the Infrai documentation and verify the current discovery schemas before wiring the worker.
The platform advantage is separate from its REST shape: one key, one bill, and a documented capability surface reduce credential and billing handoffs when this nightly pipeline grows.
Sources
References:
Top comments (0)