StandardsError Handling

Error Handling

Go

  • Always return errors — never panic
  • Wrap with context: fmt.Errorf("userService.Create: %w", err)
  • Use sentinel errors for known conditions (ErrNotFound, ErrUnauthorized)
  • Map domain errors to HTTP status codes in the handler layer
  • Log errors with structured JSON (trace ID, operation, error message)
  • Report to Sentry with trace context

TypeScript

  • Use try/catch around Server Actions
  • Display user-friendly error messages via toast notifications
  • Log errors with trace ID to Axiom
  • Never expose internal error details to the client

API Error Response Format

{
  "error": {
    "code": "NOT_FOUND",
    "message": "The requested resource was not found.",
    "traceId": "abc123..."
  }
}

Idempotency errors

Status and codeWhat it meansWhat to do
409 idempotency_key_reuseThe key was already used for a different method, endpoint, caller or body.Send a new key.
409 idempotency_in_flightThe first request with this key is still running.Wait for Retry-After, then retry with the same key.
400 idempotency_key_requiredAccess tokens only: every write needs a key.Send an Idempotency-Key header with every write.

A duplicate of a running write waits up to 2 seconds for the first answer and returns it.