# 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 `eth`, `base`, `bsc`, or `sol` |
| `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:**

1. Sign the `hashToSign` with your wallet
2. Concatenate `prefix + signature`
3. Retry with the `permit` field:

```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

1. **Check the console** — Log full responses to see error details
2. **Use the playground** — Test requests interactively at [/playground](/playground)
3. **Validate addresses** — Ensure addresses are correct for the target chain
4. **Check token contract** — Some tokens have transfer restrictions
5. **Monitor connection** — Ensure WebSocket connection is stable

---

## Getting Help

If you encounter persistent errors:

1. Note the error code and message
2. Capture the full request parameters
3. Contact us at [info@chainworks.co](mailto:info@chainworks.co)
