Error Handling
Error handling is a critical aspect of API integration, ensuring your application can gracefully respond to unexpected situations. HTTP status codes provide standardized ways to communicate error types, while structured error responses give detailed information about what went wrong. Proper error handling prevents application crashes and provides better user experiences.
Error Structure
covosign returns errors in a consistent JSON format that includes a success flag, error details, and optional additional information. The 'error' object contains a machine-readable code, a human-readable message, and sometimes field-specific details. HTTP status codes follow REST conventions: 4xx for client errors (your fault) and 5xx for server errors (our fault).
Client errors (4xx) cover validation, auth, and conflicts; server errors (5xx) are transient and should be retried with backoff.
{
"code": 400,
"statusText": "Bad Request",
"message": "Invalid email format"
}
Common Codes
The table below lists frequently encountered HTTP status codes and their corresponding error codes in covosign. Status codes in the 400s indicate client-side issues that you can fix, while 400s indicate server problems. Each error code provides specific information about the type of problem encountered, helping you diagnose and resolve issues quickly.
| Status | Code | Meaning |
|---|---|---|
| 400 | VALIDATION_ERROR | Invalid request parameters |
| 401 | INVALID_API_KEY | Authentication failed |
| 429 | RATE_LIMIT_EXCEEDED | Too many requests |
Retry Strategy
When API calls fail due to transient issues (like network problems or temporary server overload), implementing a retry strategy can improve reliability. Exponential backoff increases the wait time between retries to avoid overwhelming the server. The examples below show implementations that retry up to 3 times with increasing delays, but only for server errors (5xx status codes).
- Node.js
- Python
- Java
- Bash
async function requestWithRetry(method, url, data, maxRetries = 3) {
let attempt = 0;
while (attempt < maxRetries) {
try {
const response = await axios({ method, url, data, headers: { 'X-API-Key': process.env.API_KEY } });
return response.data;
} catch (error) {
if (error.response && error.response.status < 500) throw error;
attempt++;
await new Promise(r => setTimeout(r, Math.pow(2, attempt) * 1000));
}
}
throw new Error('Max retries exceeded');
}
def request_with_retry(method, url, data=None, max_retries=3):
attempt = 0
while attempt < max_retries:
try:
response = requests.request(method, url, json=data, headers={'X-API-Key': os.getenv('API_KEY')})
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
if hasattr(e.response, 'status_code') and e.response.status_code < 500:
raise
attempt += 1
time.sleep(2 ** attempt)
raise Exception('Max retries exceeded')
public <T> T requestWithRetry(String method, String url, Object data, Class<T> responseType, int maxRetries) throws Exception {
int attempt = 0;
while (attempt < maxRetries) {
try {
HttpHeaders headers = new HttpHeaders();
headers.set("X-API-Key", apiKey);
headers.set("Content-Type", "application/json");
String jsonData = objectMapper.writeValueAsString(data);
HttpEntity<String> entity = new HttpEntity<>(jsonData, headers);
ResponseEntity<T> response = restTemplate.exchange(url,
org.springframework.http.HttpMethod.valueOf(method.toUpperCase()),
entity, responseType);
return response.getBody();
} catch (HttpClientErrorException e) {
throw e;
} catch (HttpServerErrorException e) {
attempt++;
Thread.sleep((long) (Math.pow(2, attempt) * 1000));
}
}
throw new Exception("Max retries exceeded");
}
request_with_retry() {
local method="$1"
local url="$2"
local data="$3"
local max_retries="${4:-3}"
local attempt=0
while [ $attempt -lt $max_retries ]; do
response=$(curl -s -w "%{http_code}" -X "$method" "$url" \
-H "X-API-Key: ${API_KEY}" \
-H "Content-Type: application/json" \
-d "$data")
http_code=$(echo "$response" | tail -c 3)
body=$(echo "$response" | head -n -1)
if [ "$http_code" -ge 200 ] && [ "$http_code" -lt 300 ]; then
echo "$body"
return 0
elif [ "$http_code" -ge 400 ] && [ "$http_code" -lt 500 ]; then
echo "Client error: $http_code" >&2
return 1
fi
attempt=$((attempt + 1))
sleep $((2 ** attempt))
done
echo "Max retries exceeded" >&2
return 1
}