Handling Failed Requests
Error Response Structure
When Pay-i returns an HTTP 4xx status code, the body of the response contains properties that can be used to understand and diagnose the issue.
The statusCode
and message
properties are always returned in error responses.
xproxy_error
and xproxy_result
are optional properties and their presence is dependent on the specific error, the endpoint being called, and your integration method. If the Provider returns errors, then these properties are in addition to the error response values the Provider has returned.
Availability of Error Information
The availability of Pay-i's error information (xproxy_error
and xproxy_result
) varies based on your integration method:
Integration Method | Error Response Contains | Notes |
---|---|---|
@ingest Decorator (Recommended) | Original provider error only | Pay-i error information is not accessible. Contact [email protected] if needed. |
Manual Ingest API Call | xproxy_error + xproxy_result (for limit errors) | Error information provided after the fact, when you manually submit telemetry data |
Proxy Routing (for Blocking Limits) | xproxy_error + xproxy_result (for limit errors) | Error information provided in real-time as part of the proxied provider's response |
When using Proxy Routing or making Manual Ingest API calls, any limit-related errors will include the xproxy_result
object with details about the blocked limits, as shown in the example below.
Example Unsuccessful Request (400)
"statusCode": 400,
"message": "Bad Request",
"xproxy_error": {
"code": "limit_reached",
"message": "Insufficient limit for the requested operation",
},
"xproxy_result": {
"request_id": "40000b9e-0000-7200-b63f-84710c7967bb",
"request_tags": ["all_used_tags_are_returned_for_confirmation"],
"resource_id": "42",
"use_case_id": "2f9e1c5a-7b3d-48f6-a0d9-6e4f2c8b1a3e",
"limits": {
"6e6ae496-3239-46b6-5144-08dc8c8ba991": {
"state": "blocked"
},
"07051e47-4051-44e2-5145-08dc8c8ba991": {
"state": "bocked_external"
}
},
"blocked_limit_ids": [
"6e6ae496-3239-46b6-5144-08dc8c8ba991"
]
}
Response Values
# | Field | Description |
---|---|---|
1. | statusCode | HTTP status code from the REST call. |
2. | message | Human readable error message associated with the HTTP status. |
3. | xproxy_error (optional) | Object containing additional information about the error. |
3.1 | code | See the Error Codes section for more information. These codes be leveraged to programmatically check for and handle specific errors. |
3.2 | message | Human readable error message associated with the Pay-i related error. |
4. | xproxy_result (optional) | See xproxy_result. |
Handling Errors in Provider Python SDKs
Provider SDKs will raise an APIStatusError
exception when processing a failed request. These SDKs will raise exceptions independent of Pay-i as a proxy, so it is a good defensive practice to handle these exceptions in your code.
For example, calling messages.create()
with an invalid Anthropic key should be in a try/block to handle the exception:
payi_base_url = "https://api.pay-i.com/api/v1/proxy/anthropic/"
payi_headers = {
"xProxy-Api-Key": YOUR_PAYI_KEY,
"xProxy-Forward-anthropic-version": "2023-06-01" # Required by Anthropic
}
client = anthropic.Anthropic(
base_url = payi_base_url,
auth_token = YOUR_ANTHROPIC_KEY,
default_headers=payi_headers
)
try:
message = client.messages.create(
model="claude-3-5-sonnet-20240620",
max_tokens=500,
messages=[{
"role": "user",
"content": [{
"type": "text",
"text": "Say 'This API call will sometimes result in APIStatusError exceptions.'"
}]
}]
)
except anthropic.APIStatusError as e:
response = e.response.json()
The response will contain both Anthropic's type
and error
properties, along with Pay-i' statusCode
, message
, xproxy_error
properties.
> print(json.dumps(response, indent=4))
"type": "error",
"error": {
"type": "authentication_error",
"message": "invalid x-api-key"
},
"xproxy_error": {
"code": "provider_error",
"message": "The downstream provider returned an error."
},
"statusCode": 401,
"message": "Unauthorized"
Updated 10 days ago