Dashboard

Error Handling

Handle API errors with typed error classes, automatic retries, and structured error responses.

Error Response Format

All API errors return a JSON object with a consistent structure:

{
  "error": "not_found",
  "message": "No NDC found for code 0000-0000-00",
  "code": "NDC_NOT_FOUND"
}
Field Type Description
error string Machine-readable error type (e.g., "validation_error", "not_found")
message string Human-readable description of what went wrong
code string? Optional error code for specific error conditions

HTTP Status Codes

Status Error Type When It Happens
400 ValidationError Invalid input — missing required parameters, bad format
401 AuthenticationError Missing or invalid API key / OAuth token
403 ForbiddenError Valid credentials but insufficient scopes
404 NotFoundError The requested resource does not exist
429 RateLimitError Per-second rate limit exceeded
429 QuotaExceededError Monthly quota exhausted
500 ServerError Internal server error
502 ServerError Bad gateway
503 ServerError Service temporarily unavailable

SDK Typed Errors

The @fhirfly-io/terminology SDK maps every API error to a typed error class. This lets you handle specific error conditions without parsing status codes or response bodies.

Node.js
import {
  Fhirfly,
  NotFoundError,
  RateLimitError,
  ValidationError,
  AuthenticationError,
  QuotaExceededError,
} from "@fhirfly-io/terminology";

const client = new Fhirfly({ apiKey: "your-api-key" });

try {
  const ndc = await client.ndc.lookup("0000-0000-00");
} catch (err) {
  if (err instanceof NotFoundError) {
    // The code doesn't exist
    console.log(`Not found: ${err.code_type} ${err.code_value}`);
  } else if (err instanceof RateLimitError) {
    // Rate limited — SDK will auto-retry, but you can inspect details
    console.log(`Rate limited. Retry after: ${err.retryAfter}s`);
  } else if (err instanceof QuotaExceededError) {
    // Monthly quota exhausted — no auto-retry
    console.log(`Quota used: ${err.quotaUsed} / ${err.quotaLimit}`);
  } else if (err instanceof ValidationError) {
    // Bad input
    console.log(`Invalid input: ${err.message} (field: ${err.field})`);
  } else if (err instanceof AuthenticationError) {
    // Bad credentials
    console.log("Check your API key");
  } else {
    throw err; // Unexpected error
  }
}

Error Class Reference

Class Status Key Properties
ApiError any statusCode, code, details — base class for all API errors
AuthenticationError 401 Extends ApiError
ValidationError 400 field — the input field that failed validation
NotFoundError 404 code_type, code_value — what was looked up
RateLimitError 429 retryAfter, limit, remaining, reset
QuotaExceededError 429 quotaLimit, quotaUsed, quotaResetDate
ServerError 5xx Extends ApiError
NetworkError cause — the underlying network error
TimeoutError timeoutMs — the timeout threshold that was exceeded

All typed error classes extend FhirflyError, which extends the standard Error class.

Retry Behavior

The SDK includes built-in retry logic with exponential backoff for transient errors:

Error Type Auto-Retry Notes
RateLimitError (429) Yes Respects Retry-After header
ServerError (5xx) Yes Up to 3 retries with exponential backoff
NetworkError Yes Connection failures, DNS errors
TimeoutError Yes Request timeouts
ValidationError (400) No Bad input — fix the request
AuthenticationError (401) No Bad credentials — fix the key
NotFoundError (404) No Resource doesn't exist
QuotaExceededError (429) No Monthly quota exhausted

Configuring Retries

Node.js
const client = new Fhirfly({
  apiKey: "your-api-key",
  maxRetries: 5,      // Default: 3
  timeout: 30_000,    // Default: 10_000 (10 seconds)
});

Set maxRetries: 0 to disable automatic retries entirely.

Network Errors

NetworkError and TimeoutError are thrown when the SDK cannot reach the API server. These are not HTTP errors — they occur before any response is received.

Node.js
import { Fhirfly, NetworkError, TimeoutError } from "@fhirfly-io/terminology";

try {
  const result = await client.ndc.lookup("0069-0151-01");
} catch (err) {
  if (err instanceof TimeoutError) {
    console.log(`Request timed out after ${err.timeoutMs}ms`);
  } else if (err instanceof NetworkError) {
    console.log(`Network error: ${err.message}`);
    console.log(`Cause: ${err.cause?.message}`);
  }
}

See Also