thefaqapp
Skip to main content

Errors

API error codes, response format, and best practices for handling errors in TheFAQApp integrations.

Error Handling

When an API request fails, the response includes a consistent JSON envelope with a machine-readable error code, a human-friendly message, and optional details. This makes it straightforward to build reliable error handling into any integration.

Error Response Format

All errors follow this structure:

{
  "error": {
    "code": "error_code",
    "message": "Human-readable description",
    "details": {}
  }
}

The code field is stable and safe to match against in application logic. The message field may change over time and is intended for logging or developer-facing output. The details field provides additional context when available — for example, field-level validation issues.

Error Codes Reference

CodeHTTP StatusDescription
unauthorized401Missing or invalid API key. Check the Authorization header format.
forbidden403The API key doesn't have the required scope for this operation.
not_found404The requested resource doesn't exist or belongs to a different organization.
conflict409A resource with the same slug already exists. Choose a different slug or let the system auto-generate one.
validation_error400The request body failed schema validation. See details for field-level errors.
invalid_json400The request body couldn't be parsed as JSON. Verify the Content-Type header is application/json.
has_questions400The category contains questions and can't be deleted directly. Reassign or remove the questions first.
rate_limit_exceeded429Too many requests in the current window. Wait for the Retry-After period before retrying.
invalid_request400A required path parameter (like organization slug) is missing or malformed.

Validation Errors

When request body validation fails, the details field contains structured error information formatted by Zod:

{
  "error": {
    "code": "validation_error",
    "message": "Invalid request body",
    "details": {
      "fieldErrors": {
        "question": ["String must contain at least 1 character(s)"]
      },
      "formErrors": []
    }
  }
}

Each key in fieldErrors maps to an input field, and the value is an array of issues for that field. The formErrors array captures issues that apply to the request as a whole rather than a specific field.

Handling Errors in the SDK

The TypeScript SDK provides typed error classes so you can handle failures precisely without parsing raw responses:

import {
  FAQAPIError,
  FAQValidationError,
  FAQNotFoundError,
  FAQRateLimitError,
  FAQNetworkError,
  FAQTimeoutError,
} from '@faqapp/core';

try {
  await client.questions.create({ question: '', answer: '' });
} catch (error) {
  if (error instanceof FAQNotFoundError) {
    // Resource not found (404)
    console.error(error.message);
  }
  if (error instanceof FAQValidationError) {
    // Invalid input (400/422) — field-level errors available
    console.error(error.errors); // ValidationIssue[]
  }
  if (error instanceof FAQRateLimitError) {
    // Rate limited (429) — retry guidance available
    console.error(`Retry after ${error.retryAfter}s`);
  }
  if (error instanceof FAQAPIError) {
    // Catch-all for any API error (4xx/5xx)
    console.error(error.status, error.message, error.requestId);
  }
  if (error instanceof FAQNetworkError) {
    // Network-level failure (DNS, connection refused, etc.)
    console.error(error.message);
  }
  if (error instanceof FAQTimeoutError) {
    // Request exceeded the configured timeout
    console.error(`Timed out after ${error.timeoutMs}ms`);
  }
}

Best Practices

  • Always check the code field rather than parsing the message string. Codes are stable across API versions.
  • Implement exponential backoff for rate_limit_exceeded errors. The Retry-After header tells you exactly how long to wait.
  • Log the full error response including details to make debugging easier in production.
  • Display user-friendly messages based on the error code rather than exposing raw API messages to end users.
  • Handle network failures gracefully — timeouts and connection errors are distinct from API-level errors and may need different retry strategies.