Error Handling
Understand API error responses, status codes, and implement robust error handling with retry logic and best practices
Errors
The Thrive Public API uses conventional HTTP response codes and returns standardized error responses to indicate the success or failure of requests.
HTTP Status Codes
| Status Code | Description |
|---|---|
200 | Success - Request completed successfully |
201 | Created - Resource created successfully (e.g., new application or document) |
400 | Bad Request - Invalid request parameters or malformed request |
401 | Unauthorized - Invalid or missing authentication credentials |
403 | Forbidden - Valid credentials but insufficient permissions |
404 | Not Found - Requested resource does not exist |
422 | Unprocessable Entity - Valid request format but business logic error |
429 | Too Many Requests - Rate limit exceeded |
500 | Internal Server Error - Server error occurred |
503 | Service Unavailable - Service temporarily unavailable |
504 | Gateway Timeout - Upstream service did not respond in time |
Error Response Format
All errors follow this consistent structure:
{
"timestamp": "2024-01-15T10:30:00.000Z",
"statusCode": 400,
"result": {
"data": null,
"error": {
"message": "Human-readable error description",
"code": "MACHINE_READABLE_ERROR_CODE",
"details": {
"field": "additional_context"
}
}
}
}Common Error Codes
Authentication Errors
Invalid Credentials
{
"statusCode": 401,
"result": {
"data": null,
"error": {
"message": "Invalid client credentials provided",
"code": "INVALID_CREDENTIALS"
}
}
}Expired Token
{
"statusCode": 401,
"result": {
"data": null,
"error": {
"message": "Access token has expired",
"code": "TOKEN_EXPIRED",
"details": {
"expired_at": "2024-01-15T10:30:00.000Z"
}
}
}
}Missing Authorization
{
"statusCode": 401,
"result": {
"data": null,
"error": {
"message": "Authorization header is required",
"code": "MISSING_AUTHORIZATION"
}
}
}Validation Errors
Missing Required Fields
{
"statusCode": 400,
"result": {
"data": null,
"error": {
"message": "Required fields are missing",
"code": "VALIDATION_ERROR",
"details": {
"missing_fields": ["borrower.email", "loan_amount"]
}
}
}
}Invalid Field Values
{
"statusCode": 400,
"result": {
"data": null,
"error": {
"message": "Invalid field values provided",
"code": "VALIDATION_ERROR",
"details": {
"invalid_fields": {
"loan_amount": "Must be between 1,000 and 100,000",
"borrower.email": "Must be a valid email address"
}
}
}
}
}Business Logic Errors
Application Not Found
{
"statusCode": 404,
"result": {
"data": null,
"error": {
"message": "Loan application not found",
"code": "APPLICATION_NOT_FOUND",
"details": {
"application_uid": "app_123456789"
}
}
}
}Application Already Exists
{
"statusCode": 422,
"result": {
"data": null,
"error": {
"message": "Application already exists for this borrower and project",
"code": "DUPLICATE_APPLICATION",
"details": {
"existing_application_uid": "app_987654321"
}
}
}
}Insufficient Funds
{
"statusCode": 422,
"result": {
"data": null,
"error": {
"message": "Insufficient available balance for draw request",
"code": "INSUFFICIENT_BALANCE",
"details": {
"requested_amount": 15000.00,
"available_balance": 10000.00
}
}
}
}File Upload Errors
File Too Large
{
"statusCode": 400,
"result": {
"data": null,
"error": {
"message": "File size exceeds maximum allowed limit",
"code": "FILE_TOO_LARGE",
"details": {
"max_file_size": "10MB",
"received_file_size": "15.2MB"
}
}
}
}Invalid File Type
{
"statusCode": 400,
"result": {
"data": null,
"error": {
"message": "File type not supported",
"code": "INVALID_FILE_TYPE",
"details": {
"allowed_types": ["image/jpeg", "image/png", "application/pdf"],
"received_type": "application/zip"
}
}
}
}Rate Limiting Errors
Rate Limit Exceeded
{
"statusCode": 429,
"result": {
"data": null,
"error": {
"message": "Rate limit exceeded. Try again later",
"code": "RATE_LIMIT_EXCEEDED",
"details": {
"limit": 1000,
"window": "1 hour",
"reset_at": "2024-01-15T11:00:00.000Z"
}
}
}
}Error Handling Best Practices
1. Always Check Status Code
const response = await fetch('/api/application', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(applicationData)
});
if (!response.ok) {
const error = await response.json();
console.error('API Error:', error.result.error);
throw new Error(error.result.error.message);
}
const result = await response.json();2. Handle Specific Error Codes
function handleApiError(error) {
switch (error.code) {
case 'TOKEN_EXPIRED':
// Refresh token and retry request
return refreshTokenAndRetry();
case 'VALIDATION_ERROR':
// Show field-specific error messages
showFieldErrors(error.details.invalid_fields);
break;
case 'RATE_LIMIT_EXCEEDED':
// Implement exponential backoff
const resetTime = new Date(error.details.reset_at);
return retryAfter(resetTime);
case 'APPLICATION_NOT_FOUND':
// Redirect to application creation
redirectToCreateApplication();
break;
default:
// Generic error handling
showGenericError(error.message);
}
}3. Implement Retry Logic
async function apiRequestWithRetry(url, options, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const response = await fetch(url, options);
if (response.ok) {
return response;
}
const error = await response.json();
// Don't retry client errors (4xx) except 429
if (response.status >= 400 && response.status < 500 && response.status !== 429) {
throw new Error(error.result.error.message);
}
// Exponential backoff for retryable errors
if (attempt < maxRetries) {
const delay = Math.pow(2, attempt) * 1000; // 2s, 4s, 8s
await new Promise(resolve => setTimeout(resolve, delay));
}
} catch (error) {
if (attempt === maxRetries) {
throw error;
}
}
}
}4. Log Errors for Debugging
function logApiError(endpoint, error, requestData) {
console.error('API Error Details:', {
endpoint,
statusCode: error.statusCode,
errorCode: error.result.error.code,
message: error.result.error.message,
details: error.result.error.details,
requestData,
timestamp: error.timestamp
});
}Error Code Reference
Authentication (AUTH_*)
INVALID_CREDENTIALS- Client ID/secret combination is invalidTOKEN_EXPIRED- Access token has expiredMISSING_AUTHORIZATION- Authorization header not providedINVALID_TOKEN- Token format is invalid or corrupted
Validation (VALIDATION_*)
VALIDATION_ERROR- Request data fails validation rulesMISSING_REQUIRED_FIELD- Required field not providedINVALID_FIELD_VALUE- Field value doesn't meet constraintsINVALID_JSON- Request body is not valid JSON
Business Logic (BUSINESS_*)
APPLICATION_NOT_FOUND- Referenced application doesn't existDUPLICATE_APPLICATION- Application already existsINSUFFICIENT_BALANCE- Not enough funds availableAPPLICATION_NOT_ELIGIBLE- Application status doesn't allow operationLOAN_ALREADY_FUNDED- Loan has already been disbursed
System (SYSTEM_*)
INTERNAL_ERROR- Unexpected server error occurredSERVICE_UNAVAILABLE- External service dependency failedMAINTENANCE_MODE- System is in maintenance modeRATE_LIMIT_EXCEEDED- Too many requests sent
File Operations (FILE_*)
FILE_TOO_LARGE- File exceeds size limitINVALID_FILE_TYPE- File type not supportedFILE_UPLOAD_FAILED- File upload process failedFILE_CORRUPTED- File appears to be corrupted
Updated 18 days ago
