Error Handling
This guide explains how Caret API reports errors and the best practices for handling them in your applications.
When an error occurs, the Caret API returns:
- An appropriate HTTP status code
- A JSON response body with error details
All error responses have the following structure:
{
"error": {
"code": "error_code",
"message": "A human-readable error message",
"param": "The parameter that caused the error (if applicable)",
"type": "error_type"
}
}
Error Properties
Property | Description |
---|
code | A string identifier for the error |
message | A human-readable description of the error |
param | The parameter that caused the error (if applicable) |
type | The type of error that occurred |
Common HTTP Status Codes
Status Code | Description |
---|
400 | Bad Request - The request contains invalid parameters |
401 | Unauthorized - No valid API key provided |
403 | Forbidden - The API key doesn’t have permission to perform the request |
404 | Not Found - The requested resource doesn’t exist |
409 | Conflict - The request conflicts with another request or the resource’s state |
422 | Unprocessable Entity - The request was well-formed but contains semantic errors |
429 | Too Many Requests - Rate limit exceeded |
500 | Internal Server Error - Something went wrong on Caret’s end |
Error Types
Authentication Errors
{
"error": {
"code": "invalid_api_key",
"message": "The API key provided is invalid",
"type": "authentication_error"
}
}
Validation Errors
{
"error": {
"code": "invalid_parameter",
"message": "The 'title' parameter must be a string",
"param": "title",
"type": "validation_error"
}
}
Rate Limit Errors
{
"error": {
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded. Please retry after 35 seconds.",
"retry_after": 35,
"type": "rate_limit_error"
}
}
Resource Errors
{
"error": {
"code": "resource_not_found",
"message": "The requested note could not be found",
"param": "note_id",
"type": "resource_error"
}
}
Best Practices for Error Handling
1. Check HTTP Status Codes
Always check the HTTP status code of the response before attempting to process it. Different status codes indicate different types of errors that may require different handling strategies.
2. Parse the Error Object
Extract and log the detailed error information from the response body to help with debugging.
3. Handle Rate Limits Properly
When you receive a 429 Too Many Requests
error, use the retry_after
value to determine when to retry the request.
4. Implement Exponential Backoff
For transient errors (like 500
errors), implement an exponential backoff strategy to retry the request after increasing intervals.
5. Display User-Friendly Messages
Don’t expose raw API error messages to end users. Instead, translate them into more user-friendly messages for your application’s UI.
Code Examples
JavaScript
async function makeApiRequest(url, options) {
try {
const response = await fetch(url, options);
if (!response.ok) {
const errorData = await response.json();
// Handle specific error types
switch (response.status) {
case 401:
// Handle authentication errors
console.error('Authentication failed:', errorData.error.message);
// Redirect to login or refresh token
break;
case 404:
// Handle not found errors
console.error('Resource not found:', errorData.error.message);
break;
case 429:
// Handle rate limit errors
const retryAfter = errorData.error.retry_after || 60;
console.error(`Rate limited. Retry after ${retryAfter} seconds`);
// Implement retry logic
break;
default:
// Handle other errors
console.error('API error:', errorData.error.message);
}
throw new Error(errorData.error.message);
}
return await response.json();
} catch (error) {
// Handle network errors
console.error('Request failed:', error.message);
throw error;
}
}
Python
import requests
import time
def make_api_request(url, options, max_retries=3):
retries = 0
while retries < max_retries:
try:
response = requests.request(options.get('method', 'GET'), url, **options)
if response.ok:
return response.json()
error_data = response.json()
error = error_data.get('error', {})
# Handle specific error types
if response.status_code == 429:
retry_after = error.get('retry_after', 2 ** retries)
print(f"Rate limited. Retrying after {retry_after} seconds...")
time.sleep(retry_after)
retries += 1
continue
if response.status_code >= 500:
# Server error, retry with backoff
backoff_time = 2 ** retries
print(f"Server error. Retrying after {backoff_time} seconds...")
time.sleep(backoff_time)
retries += 1
continue
# Client error, don't retry
print(f"API error: {error.get('message')}")
raise Exception(error.get('message'))
except requests.exceptions.RequestException as e:
# Network error, retry with backoff
if retries == max_retries - 1:
raise e
backoff_time = 2 ** retries
print(f"Request failed: {str(e)}. Retrying after {backoff_time} seconds...")
time.sleep(backoff_time)
retries += 1
raise Exception("Maximum retries reached")
Next Steps