Error Handling
AS2aaS provides comprehensive error handling with detailed error responses, consistent status codes, and actionable error messages to facilitate robust application integration.
Error Response Format
All API errors follow a standardized response structure:
{
"error": {
"type": "error_category",
"code": "specific_error_identifier",
"message": "Human-readable error description",
"details": {
"field": "parameter_name",
"provided": "invalid_value",
"expected": "valid_format_description"
}
}
}
HTTP Status Codes
Code | Status | Description | Usage |
---|---|---|---|
200 | OK | Request successful | GET, PATCH, DELETE operations |
201 | Created | Resource created | POST operations |
400 | Bad Request | Invalid request syntax | Malformed JSON, invalid parameters |
401 | Unauthorized | Authentication failed | Invalid or missing API key |
403 | Forbidden | Access denied | Insufficient permissions |
404 | Not Found | Resource not found | Invalid resource ID |
422 | Unprocessable Entity | Validation failed | Business logic validation errors |
429 | Too Many Requests | Rate limit exceeded | API rate limiting |
500 | Internal Server Error | Server error | Platform errors |
Error Categories
Authentication Errors
Invalid API Key:
{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "The provided API key is invalid or has been revoked"
}
}
Expired API Key:
{
"error": {
"type": "authentication_error",
"code": "api_key_expired",
"message": "The API key has expired and must be renewed"
}
}
Authorization Errors
Insufficient Permissions:
{
"error": {
"type": "authorization_error",
"code": "insufficient_scope",
"message": "The API key does not have required permissions for this operation",
"details": {
"required_scope": "write",
"current_scopes": ["read"]
}
}
}
IP Address Restricted:
{
"error": {
"type": "authorization_error",
"code": "ip_not_allowed",
"message": "Requests from this IP address are not permitted",
"details": {
"client_ip": "203.0.113.100",
"allowed_ips": ["203.0.113.1", "203.0.113.2"]
}
}
}
Validation Errors
Missing Required Field:
{
"error": {
"type": "validation_error",
"code": "missing_required_field",
"message": "Required field is missing from request",
"details": {
"field": "partner_id",
"provided": null,
"expected": "string (partner identifier)"
}
}
}
Invalid Field Format:
{
"error": {
"type": "validation_error",
"code": "invalid_field_format",
"message": "Field value does not match expected format",
"details": {
"field": "email",
"provided": "invalid-email",
"expected": "valid email address format"
}
}
}
Resource Errors
Partner Not Found:
{
"error": {
"type": "resource_error",
"code": "partner_not_found",
"message": "Specified trading partner does not exist",
"details": {
"partner_id": "prt_nonexistent",
"suggestion": "Verify partner ID and ensure partner exists"
}
}
}
Certificate Not Found:
{
"error": {
"type": "resource_error",
"code": "certificate_not_found",
"message": "Specified certificate does not exist or is not accessible",
"details": {
"certificate_id": "cert_invalid",
"suggestion": "Verify certificate ID and access permissions"
}
}
}
Processing Errors
Message Processing Failed:
{
"error": {
"type": "processing_error",
"code": "message_processing_failed",
"message": "Message could not be processed due to content issues",
"details": {
"stage": "encryption",
"reason": "Partner encryption certificate not configured"
}
}
}
Transmission Failed:
{
"error": {
"type": "transmission_error",
"code": "partner_endpoint_unreachable",
"message": "Unable to connect to partner endpoint",
"details": {
"partner_url": "https://partner.com/as2",
"error_details": "Connection timeout after 30 seconds"
}
}
}
Rate Limiting Errors
Rate Limit Exceeded:
{
"error": {
"type": "rate_limit_error",
"code": "rate_limit_exceeded",
"message": "API rate limit exceeded for this key",
"details": {
"limit": 300,
"window": "60 seconds",
"retry_after": 45
}
}
}
Error Handling Implementation
JavaScript/Node.js
class AS2ErrorHandler {
static handleError(error, operation) {
if (error.response) {
const errorData = error.response.data.error;
switch (errorData.code) {
case 'rate_limit_exceeded':
return this.handleRateLimit(error, operation);
case 'invalid_partner':
return this.handleInvalidPartner(errorData, operation);
case 'certificate_expired':
return this.handleExpiredCertificate(errorData, operation);
default:
return this.handleGenericError(errorData, operation);
}
} else if (error.request) {
return this.handleNetworkError(error, operation);
} else {
return this.handleRequestError(error, operation);
}
}
static async handleRateLimit(error, operation) {
const retryAfter = error.response.headers['retry-after'] || 60;
console.log(`Rate limited. Retrying ${operation} after ${retryAfter} seconds`);
await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
return { retry: true, delay: retryAfter };
}
static handleInvalidPartner(errorData, operation) {
console.error(`Invalid partner for ${operation}:`, errorData.details);
return {
retry: false,
action: 'verify_partner_configuration',
suggestion: errorData.details.suggestion
};
}
}
Python
import time
import logging
from typing import Dict, Any, Optional
class AS2ErrorHandler:
@staticmethod
def handle_api_error(error_response: Dict[str, Any], operation: str) -> Dict[str, Any]:
"""Handle AS2aaS API errors with appropriate recovery strategies"""
error_data = error_response.get('error', {})
error_code = error_data.get('code')
handlers = {
'rate_limit_exceeded': AS2ErrorHandler._handle_rate_limit,
'invalid_partner': AS2ErrorHandler._handle_invalid_partner,
'certificate_expired': AS2ErrorHandler._handle_expired_certificate,
'transmission_timeout': AS2ErrorHandler._handle_transmission_timeout
}
handler = handlers.get(error_code, AS2ErrorHandler._handle_generic_error)
return handler(error_data, operation)
@staticmethod
def _handle_rate_limit(error_data: Dict, operation: str) -> Dict[str, Any]:
retry_after = error_data.get('details', {}).get('retry_after', 60)
logging.warning(f"Rate limited for {operation}. Retrying after {retry_after} seconds")
time.sleep(retry_after)
return {'retry': True, 'delay': retry_after}
@staticmethod
def _handle_invalid_partner(error_data: Dict, operation: str) -> Dict[str, Any]:
details = error_data.get('details', {})
logging.error(f"Invalid partner for {operation}: {details}")
return {
'retry': False,
'action': 'verify_partner_configuration',
'suggestion': details.get('suggestion')
}
Java
public class AS2ErrorHandler {
private static final Logger logger = LoggerFactory.getLogger(AS2ErrorHandler.class);
public static ErrorResponse handleAPIError(HttpResponse<String> response, String operation) {
try {
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> errorResponse = mapper.readValue(response.body(), Map.class);
Map<String, Object> error = (Map<String, Object>) errorResponse.get("error");
String errorCode = (String) error.get("code");
switch (errorCode) {
case "rate_limit_exceeded":
return handleRateLimit(error, operation);
case "invalid_partner":
return handleInvalidPartner(error, operation);
case "certificate_expired":
return handleExpiredCertificate(error, operation);
default:
return handleGenericError(error, operation);
}
} catch (Exception e) {
logger.error("Failed to parse error response", e);
return new ErrorResponse(false, "Failed to parse error response");
}
}
private static ErrorResponse handleRateLimit(Map<String, Object> error, String operation) {
Map<String, Object> details = (Map<String, Object>) error.get("details");
Integer retryAfter = (Integer) details.get("retry_after");
logger.warn("Rate limited for {}. Retrying after {} seconds", operation, retryAfter);
try {
Thread.sleep(retryAfter * 1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return new ErrorResponse(true, "Rate limit handled");
}
}
Best Practices
Error Recovery
- Implement exponential backoff for transient errors
- Use circuit breaker patterns for partner endpoint failures
- Log all errors with sufficient context for debugging
- Monitor error rates and patterns for system health
Monitoring
- Track error rates by error type and partner
- Set up alerts for critical error conditions
- Implement health checks for dependent services
- Monitor API response times and success rates
Development
- Use test environment for error scenario testing
- Implement comprehensive error handling in all integrations
- Document error handling procedures for operations teams
- Test error scenarios during integration development