Error Handling
Handle errors gracefully in your Sekuire agents.
Error Types
| Error | Description | Recoverable |
|---|---|---|
AuthenticationError | Invalid or expired credentials | Yes (refresh) |
NetworkError | Connection failed | Yes (retry) |
RateLimitError | Too many requests | Yes (backoff) |
PolicyViolationError | Action blocked by policy | No |
ToolExecutionError | Tool failed to execute | Depends |
LLMError | LLM provider error | Yes (retry) |
TimeoutError | Operation timed out | Yes (retry) |
Catching Errors
- TypeScript
- Python
import {
SekuireError,
AuthenticationError,
PolicyViolationError,
RateLimitError,
ToolExecutionError
} from '@sekuire/sdk';
try {
const response = await agent.chat('Do something risky');
} catch (error) {
if (error instanceof PolicyViolationError) {
console.error('Action blocked:', error.policy, error.action);
// Cannot retry - policy blocks this action
} else if (error instanceof RateLimitError) {
console.log('Rate limited, retry after:', error.retryAfter);
await sleep(error.retryAfter);
// Retry the request
} else if (error instanceof AuthenticationError) {
console.error('Auth failed:', error.message);
await sdk.refreshToken();
// Retry the request
} else if (error instanceof ToolExecutionError) {
console.error('Tool failed:', error.toolName, error.message);
// Handle tool-specific error
} else if (error instanceof SekuireError) {
console.error('Sekuire error:', error.code, error.message);
} else {
throw error; // Unknown error
}
}
from sekuire_sdk.errors import (
SekuireError,
AuthenticationError,
PolicyViolationError,
RateLimitError,
ToolExecutionError
)
try:
response = await agent.chat('Do something risky')
except PolicyViolationError as e:
print(f'Action blocked: {e.policy} - {e.action}')
# Cannot retry - policy blocks this action
except RateLimitError as e:
print(f'Rate limited, retry after: {e.retry_after}')
await asyncio.sleep(e.retry_after)
# Retry the request
except AuthenticationError as e:
print(f'Auth failed: {e.message}')
await sdk.refresh_token()
# Retry the request
except ToolExecutionError as e:
print(f'Tool failed: {e.tool_name} - {e.message}')
except SekuireError as e:
print(f'Sekuire error: {e.code} - {e.message}')
except Exception as e:
raise # Unknown error
Retry Strategies
Exponential Backoff
- TypeScript
- Python
import { withRetry, ExponentialBackoff } from '@sekuire/sdk';
const response = await withRetry(
() => agent.chat('Hello'),
{
strategy: new ExponentialBackoff({
initialDelay: 1000, // 1 second
maxDelay: 30000, // 30 seconds
multiplier: 2,
maxRetries: 5
}),
retryOn: [RateLimitError, NetworkError, TimeoutError]
}
);
from sekuire_sdk.retry import with_retry, ExponentialBackoff
response = await with_retry(
lambda: agent.chat('Hello'),
strategy=ExponentialBackoff(
initial_delay=1.0, # 1 second
max_delay=30.0, # 30 seconds
multiplier=2,
max_retries=5
),
retry_on=[RateLimitError, NetworkError, TimeoutError]
)
Custom Retry Logic
async function chatWithRetry(message: string, maxRetries = 3) {
let lastError: Error;
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await agent.chat(message);
} catch (error) {
lastError = error;
if (error instanceof PolicyViolationError) {
throw error; // Don't retry policy violations
}
if (attempt < maxRetries) {
const delay = Math.min(1000 * Math.pow(2, attempt), 30000);
console.log(`Attempt ${attempt} failed, retrying in ${delay}ms`);
await sleep(delay);
}
}
}
throw lastError;
}
Error Codes
| Code | Description |
|---|---|
AUTH_INVALID_TOKEN | Install token is invalid |
AUTH_EXPIRED_TOKEN | Token has expired |
AUTH_REVOKED | Token was revoked |
POLICY_DENIED | Action denied by policy |
POLICY_TOOL_BLOCKED | Tool not allowed |
RATE_LIMIT_EXCEEDED | Too many requests |
AGENT_NOT_FOUND | Agent not in registry |
TOOL_NOT_FOUND | Tool not registered |
TOOL_EXECUTION_FAILED | Tool threw an error |
LLM_PROVIDER_ERROR | LLM API error |
NETWORK_ERROR | Connection failed |
TIMEOUT | Operation timed out |
Graceful Degradation
Handle partial failures gracefully:
async function processWithFallback(data: string) {
try {
// Try primary agent
return await primaryAgent.chat(`Process: ${data}`);
} catch (error) {
if (error instanceof PolicyViolationError) {
// Try alternative approach
console.log('Primary blocked, trying alternative');
return await fallbackAgent.chat(`Summarize: ${data}`);
}
throw error;
}
}
Logging Errors
import { SekuireError, logger } from '@sekuire/sdk';
try {
await agent.chat(message);
} catch (error) {
if (error instanceof SekuireError) {
logger.error('Agent error', {
code: error.code,
message: error.message,
context: error.context,
stack: error.stack
});
// Report to monitoring
await reportError(error);
}
}
Error Events
Listen for error events on the SDK:
sdk.on('error', (error) => {
console.error('SDK error:', error);
});
sdk.on('auth:expired', () => {
console.log('Session expired, refreshing...');
});
sdk.on('connection:lost', () => {
console.log('Connection lost, reconnecting...');
});
sdk.on('connection:restored', () => {
console.log('Connection restored');
});
Best Practices
- Always catch SekuireError - Don't let errors crash your agent
- Log errors with context - Include request ID, agent ID, timestamp
- Use appropriate retry strategies - Not all errors are retryable
- Set timeouts - Don't wait forever for responses
- Monitor error rates - Alert on unusual error patterns
- Graceful shutdown - Handle SIGTERM/SIGINT properly
// Graceful shutdown
process.on('SIGTERM', async () => {
console.log('Shutting down gracefully...');
await sdk.shutdown();
process.exit(0);
});
Next Steps
- Telemetry - Error tracking and monitoring
- Policy Enforcement - Understanding policy errors
- Beacon - Connection management