Error handling
Understanding and handling API errors effectively.
Last updated 8 months ago
HTTP Status Codes
Error Response Format
All errors return a consistent JSON structure:
{
"detail": "error_code_or_message"
}Common Errors
401 Unauthorized
Missing API Key:
{
"detail": "missing_api_key"
}Invalid API Key:
{
"detail": "invalid_api_key"
}Solution: Check your API key is correct and included in the X-API-Key header.
403 Forbidden
No Workspace Access:
{
"detail": "user_not_in_workspace"
}Solution: Verify you have access to the workspace ID you're using.
409 Conflict
Duplicate Task:
{
"detail": "task_blocked_by_another_task"
}Solution: A collection task is already running for this post. Wait for completion or check task status.
422 Validation Error
Validation errors provide detailed field-level feedback:
Invalid LinkedIn URL:
{
"detail": [
{
"type": "value_error",
"loc": ["body", "post_url"],
"msg": "Invalid LinkedIn post URL format",
"input": "https://example.com/invalid-url"
}
]
}Missing Required Field:
{
"detail": [
{
"type": "missing",
"loc": ["body", "workspace_id"],
"msg": "Field required",
"input": {
"post_url": "https://linkedin.com/posts/example",
"data_types": ["comment"]
}
}
]
}Invalid Data Types:
{
"detail": [
{
"type": "value_error",
"loc": ["body", "data_types"],
"msg": "Input should be 'comment' or 'reaction'",
"input": ["invalid_type"]
}
]
}429 Rate Limit Exceeded
{
"detail": "Rate limit exceeded"
}Domain-Specific Errors
Invalid Activity Filter
{
"detail": "Invalid activity types: invalid_type. Valid options: posters, commenters, reactors"
}
Temporary Workbook Only
{
"detail": "Currently only supports temporary workbooks. Use the export feature for permanent workbooks."
}Task Not Found
{
"detail": "task_not_found"
}Error Handling Best Practices
1. Always Check Status Codes
import requests
response = requests.post(url, json=data, headers=headers)
if response.status_code == 422:
validation_errors = response.json()["detail"]
for error in validation_errors:
print(f"Field {error['loc']}: {error['msg']}")
elif response.status_code == 409:
print("Task already running, check status instead")
elif response.status_code == 403:
print("Access denied - check workspace permissions")2. Handle Rate Limits Gracefully
import time
def make_request_with_retry(url, headers, max_retries=3):
for attempt in range(max_retries):
response = requests.get(url, headers=headers)
if response.status_code == 429:
retry_after = int(response.headers.get('Retry-After', 60))
print(f"Rate limited, waiting {retry_after} seconds...")
time.sleep(retry_after)
continue
return response
raise Exception("Max retries exceeded")3. Validate Data Before Sending
import re
def validate_linkedin_url(url):
patterns = [
r'https://www\.linkedin\.com/posts/\w+_activity-\d+',
r'https://www\.linkedin\.com/feed/update/urn:li:activity:\d+'
]
return any(re.match(pattern, url) for pattern in patterns)
def validate_payload(payload):
if not validate_linkedin_url(payload['post_url']):
raise ValueError("Invalid LinkedIn URL format")
valid_types = {'comment', 'reaction'}
if not set(payload['data_types']).issubset(valid_types):
raise ValueError(f"Invalid data types. Valid: {valid_types}")4. Handle Task Failures
def wait_for_task_completion(task_id, headers, timeout=300):
start_time = time.time()
while time.time() - start_time < timeout:
response = requests.get(f"/tasks/{task_id}/status", headers=headers)
data = response.json()
if data["status"] == "success":
return data["result"]
elif data["status"] == "failure":
raise Exception(f"Task failed: {data.get('error', 'Unknown error')}")
time.sleep(10)
raise TimeoutError("Task did not complete within timeout")Debugging Tips
1. Enable Verbose Logging
Log all requests and responses during development:
import logging
import requests
logging.basicConfig(level=logging.DEBUG)
response = requests.post(url, json=data, headers=headers)
print(f"Status: {response.status_code}")
print(f"Response: {response.text}")2. Test with curl First
Verify your requests work with curl before implementing in code:
curl -v -H "X-API-Key: test_key" \
-H "Content-Type: application/json" \
-d '{"post_url": "https://linkedin.com/posts/test", "data_types": ["comment"], "workspace_id": "test_workspace"}' \
https://production.viacurrent.com/api/workbooks/3. Common Validation Issues
Data Types:
✅
["comment"],["reaction"],["comment", "reaction"]❌
["comments"],["reactions"],["likes"]
Workspace ID:
✅
"507f1f77bcf86cd799439011"(valid ObjectId string)❌
null,"","invalid-id"