Error Handling
The Chainworks API uses consistent error responses across all endpoints.
Error Response Format
When a request fails, you receive an error response:
json
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Human-readable error description"
},
"partialResult": {
// Optional: helpful data even when the request fails
}
}The partialResult field may contain useful information even when the request fails, such as partial token data or pool information.
Common Error Codes
Connection Errors
| Code | Description | Solution |
|---|---|---|
UNAUTHORIZED | Invalid or expired auth token | Check your API credentials |
CONNECTION_TIMEOUT | Server didn't respond in time | Retry the request |
RATE_LIMITED | Too many requests | Implement backoff and retry |
Request Errors
| Code | Description | Solution |
|---|---|---|
INVALID_CHAIN | Unsupported chain identifier | Use |
INVALID_TOKEN | Token address not found | Verify the token contract address |
INVALID_WALLET | Invalid wallet address format | Check the address format |
INVALID_AMOUNT | Amount is zero or negative | Provide a valid positive amount |
MISSING_PARAMETER | Required parameter not provided | Include all required parameters |
Trading Errors
| Code | Description | Solution |
|---|---|---|
INSUFFICIENT_LIQUIDITY | Not enough liquidity for trade | Reduce trade size or try later |
PRICE_IMPACT_TOO_HIGH | Trade would cause excessive slippage | Reduce trade size |
TOKEN_NOT_TRADEABLE | Token trading is restricted | Check token contract for restrictions |
NO_ROUTE_FOUND | No DEX route available | Token may not have liquidity |
Transaction Errors
| Code | Description | Solution |
|---|---|---|
INSUFFICIENT_BALANCE | Wallet lacks funds | Add funds to wallet |
APPROVAL_REQUIRED | Token approval needed | Call approve endpoint first |
PERMIT_REQUIRED_FOR_V3_SELL | V3 pool requires permit | Sign permit and include in request |
TRANSACTION_SIMULATION_FAILED | Transaction would revert | Check parameters and balances |
NONCE_TOO_LOW | Transaction nonce already used | Use a higher nonce |
Handling Errors
TypeScript
typescript
socket.on('/evm/buy/quote', (response) => {
if (response.success) {
console.log('Quote:', response.result);
} else {
const { code, message } = response.error;
switch (code) {
case 'INSUFFICIENT_LIQUIDITY':
console.log('Not enough liquidity. Try a smaller amount.');
break;
case 'INVALID_TOKEN':
console.log('Token not found. Check the address.');
break;
default:
console.error(`Error ${code}: ${message}`);
}
// partialResult may contain useful info
if (response.partialResult) {
console.log('Partial data:', response.partialResult);
}
}
});Python
python
@sio.on("/evm/buy/quote")
def on_quote(response):
if response.get("success"):
print("Quote:", response["result"])
else:
error = response["error"]
code = error["code"]
message = error["message"]
if code == "INSUFFICIENT_LIQUIDITY":
print("Not enough liquidity. Try a smaller amount.")
elif code == "INVALID_TOKEN":
print("Token not found. Check the address.")
else:
print(f"Error {code}: {message}")
if "partialResult" in response:
print("Partial data:", response["partialResult"])V3 Pool Permit Flow
When selling tokens on UniswapV3-style pools, you may receive a PERMIT_REQUIRED_FOR_V3_SELL error:
json
{
"success": false,
"error": {
"code": "PERMIT_REQUIRED_FOR_V3_SELL",
"message": "V3 pool requires permit signature"
},
"partialResult": {
"hashToSign": "0x...",
"prefix": "0x..."
}
}To resolve:
- Sign the
hashToSignwith your wallet - Concatenate
prefix + signature - Retry with the
permitfield:
typescript
socket.emit('/evm/sell/transaction', {
// ... same params as before
permit: prefix + signature,
});Retry Strategy
For transient errors, implement exponential backoff:
typescript
async function requestWithRetry(
path: string,
params: object,
maxRetries = 3
): Promise<any> {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
const response = await makeRequest(path, params);
if (response.success) {
return response.result;
}
// Don't retry certain errors
const noRetry = ['INVALID_TOKEN', 'INVALID_WALLET', 'UNAUTHORIZED'];
if (noRetry.includes(response.error.code)) {
throw new Error(response.error.message);
}
// Exponential backoff
const delay = Math.pow(2, attempt) * 1000;
await new Promise((resolve) => setTimeout(resolve, delay));
} catch (error) {
if (attempt === maxRetries - 1) {
throw error;
}
}
}
}Debugging Tips
- Check the console — Log full responses to see error details
- Use the playground — Test requests interactively at /playground
- Validate addresses — Ensure addresses are correct for the target chain
- Check token contract — Some tokens have transfer restrictions
- Monitor connection — Ensure WebSocket connection is stable
Getting Help
If you encounter persistent errors:
- Note the error code and message
- Capture the full request parameters
- Contact us at info@chainworks.co