Tiny Rebrand DocsHome

Error Handling

Common errors and how to handle them gracefully in your TinyRebrand API integration

Proper error handling is crucial for building robust applications. TinyRebrand's API provides detailed error information to help you understand and resolve issues quickly.

Error Response Structure

All error responses follow a consistent format:
{
  "status": 400,
  "code": "VALIDATION_ERROR",
  "message": "Human-readable error message",
  "meta": {
    "errors": [
      {"name": "field", "error": "Specific validation error"}
    ]
  }
}

Common Error Types

Specific Error Examples

Validation Errors

{
  "status": 400,
  "code": "VALIDATION_ERROR",
  "message": "Validation failed",
  "meta": {
    "errors": [
      {"name": "title", "error": "The title field is required"},
      {"name": "url", "error": "The url must be a valid URL"},
      {"name": "slug", "error": "The slug must be unique"}
    ]
  }
}

Authentication Errors

{
  "status": 401,
  "code": "INVALID_OR_EXPIRED_TOKEN",
  "message": "Invalid or expired token",
  "meta": {
    "message": "Invalid or expired token"
  }
}

Permission Errors

{
  "status": 403,
  "code": "INSUFFICIENT_PERMISSIONS",
  "message": "Insufficient permissions",
  "meta": {
    "message": "Insufficient permissions"
  }
}

Rate Limit Errors

{
  "status": 429,
  "code": "RATE_LIMIT_ERROR",
  "message": "Too many requests from this IP, please try again later.",
  "meta": {
    "message": "Too many requests from this IP, please try again later."
  }
}

Error Codes Reference

Error CodeHTTP StatusDescription
VALIDATION_ERROR400One or more fields failed validation
INVALID_OR_EXPIRED_TOKEN401Access token is invalid or expired
INSUFFICIENT_PERMISSIONS403Token lacks required permissions
NOT_FOUND404Requested resource doesn't exist
RATE_LIMIT_ERROR429Too many requests in time window
ERROR500Internal server error

Error Handling Best Practices

1. Check the Response Status

async function makeApiCall(url, options) {
  try {
    const response = await fetch(url, options);
    const data = await response.json();
    
    if (data.status >= 400 || data.code !== 'OK') {
      throw new ApiError(data.message, data.code, data.meta);
    }
    
    return { data: data.data, meta: data.meta };
  } catch (error) {
    console.error('API call failed:', error);
    throw error;
  }
}

2. Handle Specific Error Types

function handleApiError(error) {
  switch (error.code) {
    case 'VALIDATION_ERROR':
      // Show validation errors to user
      showValidationErrors(error.meta?.errors || []);
      break;
      
    case 'INVALID_OR_EXPIRED_TOKEN':
      // Redirect to login or refresh token
      redirectToLogin();
      break;
      
    case 'INSUFFICIENT_PERMISSIONS':
      // Show permission denied message
      showPermissionError();
      break;
      
    case 'RATE_LIMIT_ERROR':
      // Implement retry with backoff
      scheduleRetry();
      break;
      
    default:
      // Generic error handling
      showGenericError(error.message);
  }
}

3. Implement Retry Logic

class ApiClient {
  async makeRequest(url, options, retries = 3) {
    for (let i = 0; i <= retries; i++) {
      try {
        const response = await fetch(url, options);
        const data = await response.json();
        
        if (data.status >= 400 || data.code !== 'OK') {
          // Handle specific errors
          if (data.code === 'RATE_LIMIT_ERROR' && i < retries) {
            const delay = Math.pow(2, i) * 1000;
            await this.sleep(delay);
            continue;
          }
          
          throw new ApiError(data.message, data.code, data.meta);
        }
        
        return data.data;
      } catch (error) {
        if (i === retries) throw error;
        
        // Exponential backoff for network errors
        await this.sleep(Math.pow(2, i) * 1000);
      }
    }
  }
  
  sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
  }
}

4. Create a Custom Error Class

class ApiError extends Error {
  constructor(message, code, meta) {
    super(message);
    this.name = 'ApiError';
    this.code = code;
    this.meta = meta;
  }
  
  isValidationError() {
    return this.code === 'VALIDATION_ERROR';
  }
  
  isAuthError() {
    return this.code === 'INVALID_OR_EXPIRED_TOKEN' || this.code === 'INSUFFICIENT_PERMISSIONS';
  }
  
  isRateLimitError() {
    return this.code === 'RATE_LIMIT_ERROR';
  }
}

User-Friendly Error Messages

Always provide clear, actionable error messages to your users:
function getUserFriendlyMessage(error) {
  const messages = {
    'VALIDATION_ERROR': 'Please check your input and try again.',
    'INVALID_OR_EXPIRED_TOKEN': 'Your session has expired. Please log in again.',
    'INSUFFICIENT_PERMISSIONS': 'You don't have permission to perform this action.',
    'RATE_LIMIT_ERROR': 'You're making requests too quickly. Please wait a moment.',
    'NOT_FOUND': 'The requested item could not be found.',
    'ERROR': 'Something went wrong on our end. Please try again later.'
  };
  
  return messages[error.code] || 'An unexpected error occurred.';
}

Debugging Tips

Getting Help

If you encounter persistent issues, please reach out to us if you experience:

  • Persistent 500 server errors
  • Unexpected 404 errors for resources that should exist
  • Rate limits that seem incorrect
  • Error messages that don't match the documentation

Contact us via Twitter or Telegram with the full error response and request details for faster assistance.