Error Handling
Learn how to handle errors and edge cases when using the Finatic SDK.
Understanding how to handle errors is crucial for building robust applications with Finatic. This guide covers error handling patterns, common error types, and best practices.
Note: All Finatic methods return a standard response format. Familiarize yourself with the response structure before diving into error handling.
Error Response Structure
When an error occurs, the response looks like this:
1{
2success: null,
3error: {
4message: "Error description",
5code?: "ERROR_CODE",
6status?: 400,
7details?: { /* additional error details */ }
8},
9warning: null
10}
11The error object contains:
message: Human-readable error description (always present)code(optional): Machine-readable error code for programmatic handlingstatus(optional): HTTP status code (401, 404, 500, etc.)details(optional): Additional context (validation errors, affected fields, etc.)
Basic Error Handling
Always check for errors before accessing data. Here's an example using listAccounts():
1const result = await finatic.v1.listAccounts();
2Then handle the response:
1// TypeScript
2if (result.success) {
3// Handle success
4const accounts = result.success.data;
5console.log('Accounts:', accounts);
6} else if (result.error) {
7// Handle error
8console.error('Error:', result.error.message);
9console.error('Code:', result.error.code);
10console.error('Status:', result.error.status);
11}
121# Python
2if result.success:
3# Handle success
4accounts = result.success['data']
5print(f"Accounts: {accounts}")
6elif result.error:
7# Handle error
8print(f"Error: {result.error['message']}")
9print(f"Code: {result.error.get('code')}")
10print(f"Status: {result.error.get('status')}")
11Error Types
Authentication Errors
Occur when authentication fails or tokens expire:
1const result = await finatic.v1.listAccounts();
2
3if (result.error?.code === 'AUTH_ERROR' || result.error?.status === 401) {
4// Token expired or invalid
5// Re-initialize the SDK or refresh the token
6const newFinatic = await FinaticConnect.init(newToken);
7}
8Common causes:
- Expired one-time token (Client SDK)
- Invalid API key (Server SDK)
- Session expired
Solution:
- Client SDK: Get a new one-time token from your backend
- Server SDK: Verify API key is correct and active
Validation Errors
Occur when request parameters are invalid:
1const result = await finatic.v1.listOrders({ accountId: 'your-account-id' });
2
3if (result.error?.status === 422) {
4// Validation error
5console.error('Validation failed:', result.error.message);
6console.error('Details:', result.error.details);
7}
8Common causes:
- Invalid parameter format
- Missing required parameters
- Parameter out of range
Solution:
- Check parameter types and formats
- Verify all required parameters are provided
- Review the API reference for parameter requirements
Not Found Errors
Occur when requested resources don't exist:
1const result = await finatic.getCompany({
2companyId: 'non-existent-id'
3});
4
5if (result.error?.status === 404) {
6// Resource not found
7console.error('Company not found');
8}
9Common causes:
- Invalid resource ID
- Resource was deleted
- Insufficient permissions
Solution:
- Verify the resource ID is correct
- Check user permissions
- Handle gracefully in your UI
Rate Limit Errors
Occur when API rate limits are exceeded:
1const result = await finatic.v1.listAccounts();
2
3if (result.error?.status === 429) {
4// Rate limited
5const retryAfter = result.error.details?.retry_after;
6console.log(`Rate limited. Retry after ${retryAfter} seconds`);
7
8// Implement exponential backoff
9await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
10// Retry the request
11}
12Solution:
- Implement exponential backoff
- Respect
Retry-Afterheaders - Consider upgrading your subscription tier
Network Errors
Occur when network requests fail:
1try {
2const result = await finatic.v1.listAccounts();
3} catch (error) {
4// Network error (not an API error)
5if (error instanceof TypeError && error.message.includes('fetch')) {
6console.error('Network error:', error.message);
7// Show user-friendly message
8// Retry with exponential backoff
9}
10}
11Common causes:
- No internet connection
- API server unreachable
- Timeout
Solution:
- Check network connectivity
- Verify
baseUrlis correct - Implement retry logic with timeouts
Error Handling Patterns
Helper Function
Create a reusable error handler:
1function handleFinaticError(result: FinaticResponse<any>) {
2 if (result.success) {
3 return { success: true, data: result.success.data };
4 }
5
6 if (result.error) {
7 const { message, code, status } = result.error;
8
9 // Log error
10 console.error(`Finatic Error [${code || status}]:`, message);
11
12 // Handle specific error types
13 switch (status) {
14 case 401:
15 return { success: false, error: 'Authentication failed. Please reconnect.' };
16 case 404:
17 return { success: false, error: 'Resource not found.' };
18 case 429:
19 return { success: false, error: 'Rate limit exceeded. Please try again later.' };
20 default:
21 return { success: false, error: message || 'An error occurred.' };
22 }
23 }
24
25 return { success: false, error: 'Unknown error occurred.' };
26 }
27
28 // Usage
29 const result = await finatic.v1.listAccounts();
30 const handled = handleFinaticError(result);
31Try-Catch for Network Errors
Wrap SDK calls in try-catch for network errors:
1async function getAccountsSafely() {
2try {
3const result = await finatic.v1.listAccounts();
4
5if (result.error) {
6// API returned an error response
7throw new Error(result.error.message);
8}
9
10return result.success?.data || [];
11} catch (error) {
12// Network error or other exception
13console.error('Failed to get accounts:', error);
14throw error;
15}
16}
17Retry Logic
Implement retry logic for transient errors:
1async function getAccountsWithRetry(maxRetries = 3) {
2for (let i = 0; i < maxRetries; i++) { try { const result=await finatic.v1.listAccounts(); if (result.success) {
3 return result.success.data; } // Don't retry on client errors (4xx) if (result.error?.status && result.error.status
4 < 500) { throw new Error(result.error.message); } // Retry on server errors (5xx) or network errors if (i <
5 maxRetries - 1) { await new Promise(resolve=> setTimeout(resolve, Math.pow(2, i) * 1000));
6 continue;
7 }
8
9 throw new Error(result.error?.message || 'Request failed');
10 } catch (error) {
11 if (i === maxRetries - 1) throw error;
12 await new Promise(resolve => setTimeout(resolve, Math.pow(2, i) * 1000));
13 }
14 }
15 }
16 ```
17
18 ## Warning Messages
19
20 Some responses may include warnings:
21
22 ```typescript
23 const result = await finatic.v1.listAccounts();
24
25 if (result.warning && result.warning.length > 0) {
26 result.warning.forEach(warning => {
27 console.warn('Warning:', warning.message);
28 // Handle warnings (e.g., show to user, log)
29 });
30 }
31 ```
32
33 Warnings don't indicate failure but may provide important information about:
34 - Deprecated features
35 - Rate limit approaching
36 - Data freshness
37 - Partial results
38
39 ## Best Practices
40
41 1. **Always check for errors** - Never assume a request succeeded
42 2. **Provide user-friendly messages** - Translate technical errors to user-friendly language
43 3. **Log errors appropriately** - Log full error details for debugging, show simplified messages to users
44 4. **Handle edge cases** - Account for network failures, timeouts, and unexpected responses
45 5. **Implement retry logic** - For transient errors (network, rate limits)
46 6. **Don't retry on client errors** - 4xx errors won't succeed on retry
47 7. **Respect rate limits** - Implement backoff and respect `Retry-After` headers
48
49 ## Common Error Scenarios
50
51 ### Session Not Initialized
52
53 ```typescript
54 // Error: "Session not initialized"
55 // Solution: Ensure SDK is initialized with init()
56 const finatic = await FinaticConnect.init(oneTimeToken);
57 ```
58
59 ### Invalid Token
60
61 ```typescript
62 // Error: "Invalid token" or 401 status
63 // Solution: Get a new one-time token from your backend
64 const newToken = await fetch('/api/get-token').then(r => r.json());
65 const finatic = await FinaticConnect.init(newToken.token);
66 ```
67
68 ### No Broker Connections
69
70 ```typescript
71 // Error: "No broker connections found"
72 // Solution: User needs to connect a broker first
73 await finatic.openPortal({ mode: 'dark' });
74 ```
75
76 ## Next Steps
77
78 1. **[Standard Response Object](/docs/quick-start/standard-response-object)** - Review the response format in
79 detail.
80 2. **[Getting Data](/docs/quick-start/getting-data)** - Learn how to retrieve accounts, orders, and positions.
81 3. **[Connecting Brokers](/docs/quick-start/connecting-brokers)** - Learn how to connect broker accounts.
82 4. **[API Reference](/docs/api-reference)** - See all available methods and their error responses.