# Error Handling

The ForePaaS API uses standard HTTP status codes to indicate the success or failure of an API request. In general, codes in the `2xx` range indicate success, codes in the `4xx` range indicate a client-side error, and codes in the `5xx` range indicate a server-side error.

All error responses follow a consistent JSON format, making it easy to handle errors programmatically.

{% hint style="info" %}
**Consistent Format:** All errors return a JSON object with `code`, `msg`, and `data` fields. The `data` field may contain additional context about the error.
{% endhint %}

## HTTP Status Codes

| Code  | Meaning               | Description                                                |
| ----- | --------------------- | ---------------------------------------------------------- |
| `200` | OK                    | The request was successful.                                |
| `201` | Created               | A new resource was successfully created.                   |
| `400` | Bad Request           | The request was malformed or contained invalid parameters. |
| `401` | Unauthorized          | The request is missing a valid API key or signature.       |
| `403` | Forbidden             | You do not have permission to access this resource.        |
| `404` | Not Found             | The requested resource could not be found.                 |
| `422` | Unprocessable Entity  | The request was well-formed but contains semantic errors.  |
| `429` | Too Many Requests     | You have exceeded the API rate limit.                      |
| `500` | Internal Server Error | An unexpected error occurred on our servers.               |
| `503` | Service Unavailable   | The service is temporarily unavailable. Try again later.   |

## Error Response Format

When an error occurs, the API will return a JSON response with the following format:

```json
{
  "code": 400,
  "msg": "Invalid request parameters",
  "data": null
}
```

| Field  | Type   | Description                                |
| ------ | ------ | ------------------------------------------ |
| `code` | number | The HTTP status code.                      |
| `msg`  | string | A human-readable error message.            |
| `data` | object | Additional error details (usually `null`). |

## Error Code Reference

In addition to HTTP status codes, the API returns specific error codes in the `msg` field to help you diagnose issues.

### Balance & Trading Errors (2xxx)

| Error Code | HTTP | Message                                          | Solution                                |
| ---------- | ---- | ------------------------------------------------ | --------------------------------------- |
| 2001       | 422  | share is not enough                              | User doesn't have enough shares to sell |
| 2002       | 422  | Available balance is insufficient                | User needs to add funds                 |
| 2003       | 422  | The withdrawal amount is too small               | Increase withdrawal amount              |
| 2004       | 422  | Available share not enough (ongoing sell orders) | Check active orders or available shares |

### Resource Not Found Errors (3xxx)

| Error Code | HTTP | Message                                  | Solution                     |
| ---------- | ---- | ---------------------------------------- | ---------------------------- |
| 3001       | 404  | outcome is not exist                     | Verify outcome ID is correct |
| 3002       | 404  | wallet address is not exist              | Check wallet address         |
| 3003       | 404  | orders open is not exist                 | Order not found              |
| 3004       | 404  | orders is not exist                      | Order not found              |
| 3005       | 404  | user is not exist / email not registered | User needs to register       |
| 3009       | 404  | market does not exist                    | Verify market ID             |
| 3012       | 404  | asset is not exist                       | Asset not found              |
| 3019       | 404  | challenge is not exist                   | Challenge not found          |
| 3020       | 404  | category is not exist                    | Use valid category ID        |

### Validation Errors (4xxx)

| Error Code | HTTP | Message                                                   | Solution                             |
| ---------- | ---- | --------------------------------------------------------- | ------------------------------------ |
| 401        | 401  | invalid token / token has expired                         | Re-authenticate user                 |
| 402        | 401  | invalid api key                                           | Check API key                        |
| 403        | 403  | Permission denied                                         | Check user permissions               |
| 400        | 400  | parameter error                                           | Verify request parameters            |
| 4001       | 400  | outcomeId is null                                         | Provide outcomeId                    |
| 4002       | 400  | email has been registered                                 | Use different email                  |
| 4003       | 401  | invalid user or password                                  | Check credentials                    |
| 4010       | 400  | Please do not submit duplicate applications               | Application already exists           |
| 4011       | 403  | Non-creators cannot create markets                        | User needs creator role              |
| 4013       | 400  | There is similar market information                       | Market too similar to existing one   |
| 4014       | 422  | market status does not allow launching a challenge        | Wrong market status for challenge    |
| 4017       | 422  | The current market status does not allow this operation   | Check market status                  |
| 4025       | 422  | market is claimed or in claiming                          | Rewards already claimed              |
| 4027       | 422  | The current status does not allow modification operations | Cannot edit market in current status |
| 4035       | 400  | Liquidity cannot be less than 100                         | Increase liquidity amount            |
| 4039       | 400  | The weights must add up to 1                              | Fix option weights                   |
| 4041       | 400  | A market with this title already exists                   | Use unique title                     |

### System Restriction Errors (5xxx)

| Error Code | HTTP | Message                                       | Solution                                |
| ---------- | ---- | --------------------------------------------- | --------------------------------------- |
| 500        | 500  | Internal server error                         | Retry with backoff                      |
| 5001       | 403  | User is prohibited from placing orders        | User trading is suspended               |
| 5002       | 403  | Market creator is not allowed to place orders | Creators cannot trade their own markets |
| 5003       | 422  | amount not in range                           | Check min/max amount limits             |
| 5007       | 422  | share is too small                            | Increase share amount                   |
| 5008       | 422  | share is too large                            | Decrease share amount                   |

### Business Logic Errors (9xxxx)

| Error Code | HTTP | Message          | Solution                          |
| ---------- | ---- | ---------------- | --------------------------------- |
| 90001      | 422  | Order is Trading | Order still in progress           |
| 90003      | 422  | market is closed | Market no longer accepting trades |
| 90005      | 500  | lock fail        | Resource locked, retry            |

## Error Response Examples

### 400 Bad Request

```json
{
  "code": 400,
  "msg": "Invalid request parameters: marketId is required",
  "data": null
}
```

### 401 Unauthorized

```json
{
  "code": 401,
  "msg": "Invalid signature",
  "data": null
}
```

### 404 Not Found

```json
{
  "code": 404,
  "msg": "Market not found",
  "data": null
}
```

### 422 Unprocessable Entity

```json
{
  "code": 422,
  "msg": "Insufficient balance",
  "data": {
    "required": 100.0,
    "available": 50.0
  }
}
```

### 429 Rate Limit Exceeded

```json
{
  "code": 429,
  "msg": "Rate limit exceeded",
  "data": {
    "retryAfter": 60,
    "limit": 50,
    "window": "1s"
  }
}
```

## Handling Errors in Your Code

### Node.js Example

```javascript
try {
  const response = await fetch(url, {
    method: 'POST',
    headers: headers,
    body: JSON.stringify(body)
  });
  
  const data = await response.json();
  
  if (data.code !== 200) {
    switch (data.code) {
      case 401:
        // Re-authenticate
        await refreshToken();
        break;
      case 429:
        // Implement backoff
        await sleep(data.data?.retryAfter * 1000 || 60000);
        break;
      case 422:
        // Handle business logic error
        console.error('Business error:', data.msg);
        break;
      default:
        console.error('API error:', data.msg);
    }
  }
} catch (error) {
  console.error('Network error:', error);
}
```

### Python Example

```python
import requests
import time

try:
    response = requests.post(url, headers=headers, json=body)
    data = response.json()
    
    if data['code'] != 200:
        if data['code'] == 401:
            # Re-authenticate
            refresh_token()
        elif data['code'] == 429:
            # Implement backoff
            retry_after = data.get('data', {}).get('retryAfter', 60)
            time.sleep(retry_after)
        elif data['code'] == 422:
            # Handle business logic error
            print(f"Business error: {data['msg']}")
        else:
            print(f"API error: {data['msg']}")
            
except requests.exceptions.RequestException as e:
    print(f"Network error: {e}")
```

## Error Handling Flow

Here's the recommended decision tree for handling API errors:

| Response Code | Error Type          | Action Required                                                                                                 | Should Retry?     |
| ------------- | ------------------- | --------------------------------------------------------------------------------------------------------------- | ----------------- |
| **2xx**       | ✅ Success           | Process response data                                                                                           | No                |
| **400**       | Bad Request         | Fix invalid parameters, review request body                                                                     | No                |
| **401**       | Unauthorized        | <p><strong>If API key:</strong> Check signature generation<br><strong>If JWT:</strong> Re-authenticate user</p> | Yes (after fix)   |
| **403**       | Forbidden           | Check user permissions and role                                                                                 | No                |
| **404**       | Not Found           | Verify resource ID exists                                                                                       | No                |
| **422**       | Business Error      | Check business constraints (balance, market status, etc.)                                                       | No                |
| **429**       | Rate Limited        | Wait with exponential backoff (see retry\_after)                                                                | Yes (after delay) |
| **500**       | Server Error        | Retry with exponential backoff (max 3 times)                                                                    | Yes               |
| **503**       | Service Unavailable | Retry with exponential backoff (max 3 times)                                                                    | Yes               |

### Quick Reference: When to Retry

```
✅ Always Retry:
  • 429 (Rate Limited) - wait for retry_after seconds
  • 500 (Server Error) - exponential backoff
  • 503 (Service Unavailable) - exponential backoff

⚠️ Retry After Fixing:
  • 401 (Unauthorized) - regenerate signature or refresh JWT token

❌ Never Retry:
  • 400 (Bad Request) - fix parameters first
  • 403 (Forbidden) - insufficient permissions
  • 404 (Not Found) - resource doesn't exist
  • 422 (Business Error) - fix business logic issue
```

## Best Practices

### 1. Always Check Response Codes

Never assume a request succeeded. Always check the `code` field in the response.

### 2. Implement Retry Logic

For `429` and `5xx` errors, implement exponential backoff:

```javascript
async function retryWithBackoff(fn, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await fn();
    } catch (error) {
      if (error.code === 429 || error.code >= 500) {
        const delay = Math.pow(2, i) * 1000; // 1s, 2s, 4s
        await sleep(delay);
      } else {
        throw error;
      }
    }
  }
  throw new Error('Max retries exceeded');
}
```

### 3. Log Errors for Debugging

Log all errors with relevant context (request ID, timestamp, parameters) for debugging:

```javascript
console.error({
  timestamp: new Date().toISOString(),
  endpoint: '/api/order/openapi/order/submit',
  error: data.msg,
  code: data.code,
  requestId: headers['X-Nonce']
});
```

### 4. Handle Authentication Errors Gracefully

When receiving a `401` error, prompt the user to re-authenticate rather than showing a generic error message.

## Common Error Scenarios

### Invalid Signature (401)

**Cause:** This is the most common error and is usually caused by an issue with your signature generation process.

**Checklist:**

* The `signContent` string is built correctly with all required fields separated by newlines
* The request path is correct and does not include the domain
* The request body is included in the signature, even if it is empty
* Your RSA private key is in the correct PKCS#8 format
* The final signature is properly Base64-encoded
* The timestamp is current (not more than 5 minutes old)
* The nonce is unique for each request

### Invalid Parameters (400)

**Cause:** The request body contains invalid or missing parameters.

**Solution:** Check the API reference for the specific endpoint to ensure that all required fields are included and have the correct data types.

### Rate Limit Exceeded (429)

**Cause:** You have sent too many requests in a short time period.

**Solution:** Implement request throttling and exponential backoff. The API allows 50 requests per second per API key.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.forepaas.org/getting-started/error-handling.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
