Skip to main content
CodePlanet Docs

Error Handling

Error codes and troubleshooting

Understanding error responses helps you build robust integrations and troubleshoot issues effectively.

Error Response Format

All errors follow a consistent structure:

{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid email format",
    "details": {
      "field": "email",
      "value": "not-an-email",
      "expected": "valid email address"
    }
  }
}

Fields

FieldTypeDescription
successbooleanAlways false for errors
error.codestringMachine-readable error code
error.messagestringHuman-readable description
error.detailsobjectAdditional context (optional)

HTTP Status Codes

StatusMeaningCommon Causes
400Bad RequestInvalid input, missing fields
401UnauthorizedInvalid/missing auth token
403ForbiddenValid auth but no permission
404Not FoundResource doesn't exist
409ConflictDuplicate resource
422UnprocessableValidation failed
429Too Many RequestsRate limit exceeded
500Internal ErrorServer-side bug
503Service UnavailableMaintenance/overload

Error Codes

Authentication Errors

CodeStatusDescription
UNAUTHORIZED401No auth token provided
INVALID_TOKEN401Token is invalid or expired
TOKEN_EXPIRED401Token has expired
INVALID_API_KEY401API key is invalid
SESSION_EXPIRED401Session has expired

Example:

{
  "success": false,
  "error": {
    "code": "TOKEN_EXPIRED",
    "message": "Your session has expired. Please log in again."
  }
}

Validation Errors

CodeStatusDescription
VALIDATION_ERROR400Input validation failed
INVALID_FORMAT400Wrong format (email, UUID, etc.)
MISSING_FIELD400Required field not provided
INVALID_VALUE400Value out of allowed range

Example:

{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Validation failed",
    "details": {
      "errors": [
        { "field": "email", "message": "Invalid email format" },
        { "field": "password", "message": "Must be at least 8 characters" }
      ]
    }
  }
}

Rate Limiting Errors

CodeStatusDescription
RATE_LIMITED429Too many requests

Headers included:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1705320600
Retry-After: 60

Example:

{
  "success": false,
  "error": {
    "code": "RATE_LIMITED",
    "message": "Rate limit exceeded. Please wait before retrying.",
    "details": {
      "limit": 100,
      "remaining": 0,
      "reset_at": "2024-01-15T10:30:00Z",
      "retry_after": 60
    }
  }
}

Resource Errors

CodeStatusDescription
NOT_FOUND404Resource doesn't exist
ALREADY_EXISTS409Duplicate resource
RESOURCE_LOCKED423Resource is locked

Payment Errors

CodeStatusDescription
PAYMENT_FAILED400Payment was declined
INVALID_SIGNATURE401Razorpay signature invalid
ORDER_EXPIRED400Payment order expired
ALREADY_PAID400Order already paid

Server Errors

CodeStatusDescription
INTERNAL_ERROR500Unexpected server error
SERVICE_UNAVAILABLE503Service temporarily down
DATABASE_ERROR500Database operation failed

Handling Errors

JavaScript/TypeScript

async function makeRequest(url: string) {
  try {
    const response = await fetch(url, {
      headers: { Authorization: `Bearer ${token}` },
    });
 
    const data = await response.json();
 
    if (!data.success) {
      // Handle API error
      switch (data.error.code) {
        case "UNAUTHORIZED":
        case "TOKEN_EXPIRED":
          // Redirect to login
          redirectToLogin();
          break;
        case "RATE_LIMITED":
          // Wait and retry
          const retryAfter = data.error.details?.retry_after || 60;
          await sleep(retryAfter * 1000);
          return makeRequest(url);
        case "VALIDATION_ERROR":
          // Show validation errors to user
          showValidationErrors(data.error.details.errors);
          break;
        default:
          // Show generic error
          showError(data.error.message);
      }
      return null;
    }
 
    return data.data;
  } catch (error) {
    // Network error
    showError("Network error. Please check your connection.");
    return null;
  }
}

Python

import requests
 
def make_request(url):
    try:
        response = requests.get(url, headers={"Authorization": f"Bearer {token}"})
        data = response.json()
        
        if not data.get("success"):
            error = data.get("error", {})
            code = error.get("code")
            
            if code in ["UNAUTHORIZED", "TOKEN_EXPIRED"]:
                refresh_token()
                return make_request(url)  # Retry
            elif code == "RATE_LIMITED":
                retry_after = error.get("details", {}).get("retry_after", 60)
                time.sleep(retry_after)
                return make_request(url)  # Retry
            else:
                raise APIError(error.get("message"))
        
        return data.get("data")
    except requests.exceptions.RequestException as e:
        raise NetworkError(str(e))

Best Practices

1. Always Check success

Don't assume a 200 status means success:

const data = await response.json();
if (!data.success) {
  // Handle error
}

2. Handle Rate Limits

Implement exponential backoff:

async function requestWithRetry(url: string, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const response = await fetch(url);
    const data = await response.json();
    
    if (data.error?.code === "RATE_LIMITED") {
      const delay = Math.pow(2, attempt) * 1000; // 1s, 2s, 4s
      await sleep(delay);
      continue;
    }
    
    return data;
  }
  throw new Error("Max retries exceeded");
}

3. Log Error Details

Include context for debugging:

if (!data.success) {
  console.error("API Error:", {
    code: data.error.code,
    message: data.error.message,
    details: data.error.details,
    endpoint: url,
    timestamp: new Date().toISOString(),
  });
}

4. Show User-Friendly Messages

Don't show raw error messages to users:

const userMessages = {
  UNAUTHORIZED: "Please log in to continue",
  RATE_LIMITED: "Too many requests. Please wait a moment.",
  NOT_FOUND: "The requested item was not found",
  INTERNAL_ERROR: "Something went wrong. Please try again later.",
};
 
const message = userMessages[error.code] || "An error occurred";
showToast(message);

Debugging

Check the Error Code

The code field is the most reliable way to handle errors programmatically.

Read the Details

The details object often contains helpful context:

  • Validation errors: Which fields failed
  • Rate limits: When you can retry
  • Conflicts: What resource already exists

Check Response Headers

Headers often contain useful info:

  • X-Request-Id: For support tickets
  • X-RateLimit-*: Rate limit status

Getting Help

If you encounter unexpected errors:

  1. Check the error code and message
  2. Review the Troubleshooting guide
  3. Search Discord for similar issues
  4. Contact Support with:
    • Error code and message
    • Request ID (from headers)
    • Steps to reproduce

Next Steps