Sign in

Error Handling

All Auva APIs return errors in a consistent JSON format. Understanding these patterns helps you build resilient integrations.


Error Response Format

Every error response follows this structure:

text
{
  "error": "Error Type",
  "message": "Human-readable description of what went wrong"
}

HTTP Status Codes

CodeMeaningWhen It Happens
400Bad RequestInvalid request body, missing required fields
401UnauthorizedMissing or expired access token
403ForbiddenValid token but insufficient permissions
404Not FoundResource doesn't exist
409ConflictDuplicate resource (e.g., username taken)
422Unprocessable EntityValidation failed (e.g., invalid email format)
429Too Many RequestsRate limit exceeded
500Internal Server ErrorSomething broke on our end

Common Error Scenarios

Invalid Credentials

text
// POST /auth/login with wrong password
{
  "error": "Unauthorized",
  "message": "Invalid email or password"
}

Token Expired

text
// GET /user/me with expired token
{
  "error": "Unauthorized",
  "message": "Token expired"
}

Action: Call POST /auth/refresh to get a new access token.

Validation Error

text
// POST /auth/register with invalid data
{
  "error": "Validation Error",
  "message": "Email must be a valid email address"
}

Resource Not Found

text
// GET /api/links/nonexistent-id
{
  "error": "Not Found",
  "message": "Link not found"
}

Username Taken

text
// POST /auth/register with existing username
{
  "error": "Conflict",
  "message": "Username is already taken"
}

Error Handling Pattern

Here's a robust error handling pattern for TypeScript:

text
type ApiError = {
  error: string;
  message: string;
};

async function apiCall<T>(url: string, options?: RequestInit): Promise<T> {
  const response = await fetch(url, {
    ...options,
    credentials: 'include',
    headers: {
      'Content-Type': 'application/json',
      ...options?.headers,
    },
  });

  if (!response.ok) {
    const error: ApiError = await response.json().catch(() => ({
      error: 'Unknown Error',
      message: 'An unexpected error occurred',
    }));

    switch (response.status) {
      case 401:
        // Try refresh, then retry
        throw new AuthError(error.message);
      case 429:
        // Implement retry with backoff
        throw new RateLimitError(error.message);
      default:
        throw new ApiCallError(error.message, response.status);
    }
  }

  return response.json();
}

Always parse error responses as JSON and display the message field to users. The error field is for programmatic handling, while message is human-readable.