Skip to content

Error Handling

DialogueDB uses standardized error responses to help you handle failures gracefully and build robust applications.

Error Response Format

All error responses follow a consistent structure:

json
{
  "error": {
    "code": "DIALOGUE_NOT_FOUND",
    "message": "Dialogue 'dlg_abc123' not found",
    "type": "not_found",
    "details": [
      {
        "field": "id",
        "code": "NOT_FOUND",
        "message": "Resource does not exist"
      }
    ],
    "requestId": "req_xyz789",
    "timestamp": "2025-11-06T21:34:21.117Z"
  }
}

Error Object Fields

FieldTypeDescription
codestringMachine-readable error code (e.g., DIALOGUE_NOT_FOUND)
messagestringHuman-readable error description
typestringError category: validation_error, not_found, conflict, rate_limit, server
detailsarrayOptional field-level validation errors
requestIdstringUnique request identifier for debugging
timestampstringISO 8601 timestamp when the error occurred

HTTP Status Codes

DialogueDB uses standard HTTP status codes to indicate the type of error:

StatusMeaningWhen Used
400Bad RequestValidation errors, missing required fields, invalid input
401UnauthorizedMissing or invalid authentication token
404Not FoundResource (dialogue, message, project) does not exist
409ConflictResource conflict (e.g., dialogue immutability violation)
429Too Many RequestsRate limit exceeded
500Internal Server ErrorUnexpected server error

Error Types

Validation Errors (400)

Returned when request data is invalid or missing required fields.

Example:

json
{
  "error": {
    "code": "MISSING_PARAMETER",
    "message": "Missing required parameter: id",
    "type": "validation_error",
    "details": [
      {
        "field": "id",
        "code": "REQUIRED",
        "message": "Dialogue ID is required"
      }
    ],
    "requestId": "req_123",
    "timestamp": "2025-11-06T21:34:21Z"
  }
}

Common validation error codes:

  • MISSING_PARAMETER - Required parameter not provided
  • INVALID_PARAMETER - Parameter format is invalid
  • MESSAGE_CONTENT_EMPTY - Message content cannot be empty
  • MESSAGE_TOO_LARGE - Message exceeds size limit
  • TOO_MANY_MESSAGES - Exceeds 50 message limit on creation
  • INVALID_MESSAGE_ARRAY - Messages must be an array
  • INVALID_ACTION - Unsupported action specified

Not Found Errors (404)

Returned when a requested resource does not exist.

Example:

json
{
  "error": {
    "code": "DIALOGUE_NOT_FOUND",
    "message": "Dialogue 'dlg_abc123' not found",
    "type": "not_found",
    "requestId": "req_456",
    "timestamp": "2025-11-06T21:34:21Z"
  }
}

Common not found error codes:

  • DIALOGUE_NOT_FOUND - Dialogue does not exist
  • MESSAGE_NOT_FOUND - Message does not exist
  • PROJECT_NOT_FOUND - Project does not exist
  • PARENT_DIALOGUE_NOT_FOUND - Parent dialogue for thread not found

Conflict Errors (409)

Returned when operation conflicts with resource state.

Example:

json
{
  "error": {
    "code": "DIALOGUE_IMMUTABLE",
    "message": "Cannot delete message: dialogues are immutable in this project",
    "type": "conflict",
    "requestId": "req_789",
    "timestamp": "2025-11-06T21:34:21Z"
  }
}

Common conflict error codes:

  • DIALOGUE_IMMUTABLE - Operation not allowed on immutable dialogue
  • DUPLICATE_ID - Resource with this ID already exists
  • RESOURCE_CONFLICT - Operation conflicts with resource state

Rate Limit Errors (429)

Returned when API rate limits are exceeded.

Example:

json
{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded. Please try again later.",
    "type": "rate_limit",
    "requestId": "req_999",
    "timestamp": "2025-11-06T21:34:21Z"
  }
}

Response headers:

http
X-RateLimit-Limit: 50
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1640000060
Retry-After: 60

Server Errors (500)

Returned for unexpected server-side errors.

Example:

json
{
  "error": {
    "code": "INTERNAL_ERROR",
    "message": "An internal error occurred while processing your request",
    "type": "server",
    "requestId": "req_555",
    "timestamp": "2025-11-06T21:34:21Z"
  }
}

Error Code Reference

Validation Errors (400)

CodeHTTP StatusDescription
MISSING_PARAMETER400Required parameter missing from request
INVALID_PARAMETER400Parameter format or value is invalid
INVALID_INPUT400Input validation failed
VALIDATION_ERROR400General validation error
MESSAGE_CONTENT_EMPTY400Message content cannot be empty
MESSAGE_TOO_LARGE400Message exceeds maximum size (1MB uncompressed)
TOO_MANY_MESSAGES400Exceeds 50 message limit on creation
INVALID_MESSAGE_ARRAY400Messages parameter must be an array
EMPTY_MESSAGE_ARRAY400Messages array cannot be empty
INVALID_ACTION400Unsupported action specified
SEARCH_QUERY_TOO_SHORT400Search query must be at least 3 characters

Not Found Errors (404)

CodeHTTP StatusDescription
DIALOGUE_NOT_FOUND404Dialogue with specified ID not found
MESSAGE_NOT_FOUND404Message with specified ID not found
PROJECT_NOT_FOUND404Project does not exist
PARENT_DIALOGUE_NOT_FOUND404Parent dialogue for thread not found
RESOURCE_NOT_FOUND404Generic resource not found

Conflict Errors (409)

CodeHTTP StatusDescription
DIALOGUE_IMMUTABLE409Operation not allowed on immutable dialogue
DUPLICATE_ID409Resource with this ID already exists
RESOURCE_CONFLICT409Operation conflicts with resource state

Rate Limit & Plan Limit Errors (429)

CodeHTTP StatusDescription
RATE_LIMIT_EXCEEDED429Too many requests - retry after delay
PLAN_LIMIT_EXCEEDED429Plan quota exceeded - upgrade to continue writing. Existing data remains accessible; only new writes are blocked. No overage charges.

Server Errors (500)

CodeHTTP StatusDescription
INTERNAL_ERROR500Unexpected server error
DATABASE_ERROR500Database operation failed
TRANSACTION_FAILED500Database transaction failed

Error Handling Best Practices

1. Always Check HTTP Status Codes

typescript
const response = await fetch(url, options);

if (!response.ok) {
  const error = await response.json();

  switch (response.status) {
    case 400:
      // Validation error - fix request
      console.error('Invalid request:', error.error.message);
      break;
    case 404:
      // Not found - handle missing resource
      console.error('Resource not found:', error.error.code);
      break;
    case 429:
      // Rate limited - retry with backoff
      await sleep(parseInt(response.headers.get('Retry-After')) * 1000);
      return retry();
    case 500:
      // Server error - retry or alert
      console.error('Server error:', error.error.requestId);
      break;
  }
}

2. Use Error Codes for Logic

typescript
try {
  const dialogue = await db.getDialogue(dialogueId);
} catch (error) {
  if (error.code === 'DIALOGUE_NOT_FOUND') {
    // Create new dialogue
    return db.createDialogue({ ... });
  }

  if (error.code === 'RATE_LIMIT_EXCEEDED') {
    // Wait and retry
    await sleep(1000);
    return retry();
  }

  // Unknown error - propagate
  throw error;
}

3. Handle Validation Errors with Details

typescript
try {
  await dialogue.saveMessage(message);
} catch (error) {
  if (error.type === 'validation_error' && error.details) {
    // Show field-level errors to user
    error.details.forEach(detail => {
      console.error(`${detail.field}: ${detail.message}`);
    });
  }
}

4. Log Request IDs for Support

typescript
try {
  await api.dialogue.remove({ id: dialogueId });
} catch (error) {
  // Always log requestId for debugging
  console.error('Operation failed', {
    requestId: error.requestId,
    code: error.code,
    message: error.message
  });

  // Show friendly message to user, provide requestId for support
  alert(`Operation failed. Please contact support with ID: ${error.requestId}`);
}

5. Implement Retry Logic for Transient Errors

typescript
async function withRetry<T>(
  fn: () => Promise<T>,
  maxRetries = 3
): Promise<T> {
  let lastError;

  for (let i = 0; i < maxRetries; i++) {
    try {
      return await fn();
    } catch (error) {
      lastError = error;

      // Only retry on rate limits and server errors
      if (error.code === 'RATE_LIMIT_EXCEEDED' || error.type === 'server') {
        const delay = Math.min(1000 * Math.pow(2, i), 10000);
        await sleep(delay);
        continue;
      }

      // Don't retry validation or not found errors
      throw error;
    }
  }

  throw lastError;
}

// Usage
const dialogue = await withRetry(() => db.getDialogue(id));

6. Handle Immutability Gracefully

typescript
try {
  await dialogue.deleteMessage(messageId);
} catch (error) {
  if (error.code === 'DIALOGUE_IMMUTABLE') {
    console.error('Cannot modify messages in immutable dialogues');
    console.log('Consider creating a new dialogue with corrected messages');
  }
}

SDK Error Handling

When using the official SDK, errors are automatically parsed:

typescript
import { DialogueDB, DialogueDBError } from 'dialogue-db';

const db = new DialogueDB({ apiKey: 'DIALOGUE_DB_API_KEY' });

try {
  await db.getDialogue('invalid_id');
} catch (error) {
  if (error instanceof DialogueDBError) {
    console.log(error.code);       // 'DIALOGUE_NOT_FOUND'
    console.log(error.type);       // 'not_found'
    console.log(error.statusCode); // 404
    console.log(error.requestId);  // 'req_xyz'
    console.log(error.message);    // Human-readable message
  }
}

Testing Error Scenarios

Trigger Validation Errors

bash
# Missing required field
curl -X POST https://api.dialoguedb.com/dialogue \
  -H "Authorization: Bearer DIALOGUE_DB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

# Response: 400 with MISSING_PARAMETER

Trigger Not Found Errors

bash
# Non-existent dialogue
curl -X GET https://api.dialoguedb.com/dialogue/invalid_id \
  -H "Authorization: Bearer DIALOGUE_DB_API_KEY"

# Response: 404 with DIALOGUE_NOT_FOUND

Trigger Rate Limit Errors

bash
# Exceed rate limits
for i in {1..100}; do
  curl -X GET https://api.dialoguedb.com/dialogue \
    -H "Authorization: Bearer DIALOGUE_DB_API_KEY"
done

# Response: 429 with RATE_LIMIT_EXCEEDED

Debugging Tips

1. Use Request IDs

Every error includes a requestId. Provide this when contacting support:

Support Request:
- Request ID: req_abc123xyz
- Error Code: INTERNAL_ERROR
- Timestamp: 2025-11-06T21:34:21Z

2. Enable Debug Logging

typescript
const client = new DialogueDB({
  apiKey: 'DIALOGUE_DB_API_KEY',
  debug: true  // Log all requests and responses
});

3. Check Response Headers

Rate limit information is in headers:

typescript
const response = await fetch(url, options);
console.log('Rate Limit:', response.headers.get('X-RateLimit-Limit'));
console.log('Remaining:', response.headers.get('X-RateLimit-Remaining'));
console.log('Reset:', response.headers.get('X-RateLimit-Reset'));

Common Errors & Solutions

ErrorCauseSolution
DIALOGUE_NOT_FOUNDDialogue doesn't exist or belongs to different projectVerify dialogue ID and project access
MESSAGE_CONTENT_EMPTYEmpty message contentEnsure content field is not empty
TOO_MANY_MESSAGESMore than 50 messages on creationSplit into multiple requests
DIALOGUE_IMMUTABLEProject has immutability enabledCheck project settings or create new dialogue
RATE_LIMIT_EXCEEDEDToo many requestsImplement exponential backoff
PLAN_LIMIT_EXCEEDEDPlan quota exceededUpgrade plan — reads still work, only writes blocked
PROJECT_NOT_FOUNDInvalid project IDVerify project exists and is accessible

Support

If you encounter unexpected errors:

  1. Check the error code against this reference
  2. Note the requestId from the error response
  3. Contact support with the request ID and error details
  4. Include relevant code that triggered the error

For real-time support:

Built with DialogueDB