Error Codes
Structured error codes and the SentinelError class for predictable error handling
3 min read
Error Codes
Sentinel uses structured error codes for every exception it raises. All errors are instances of SentinelError, a frozen subclass of Error.
Import
typescript
import { SentinelError, SentinelErrorCode } from '@sentinel-sdk/core';
SentinelError
typescript
class SentinelError extends Error {
readonly code: SentinelErrorCode
readonly details?: Readonly<Record<string, unknown>>
}
SentinelError instances are frozen on construction. The code field is always a SentinelErrorCode enum member. details carries structured context about the failure.
typescript
try {
await sentinel.scanInput('...');
} catch (err) {
if (err instanceof SentinelError) {
console.log(err.code); // 'SEN5002'
console.log(err.message); // 'PromptGuard is not configured...'
console.log(err.details); // { ... } | undefined
}
}
Error Code Reference
Config Errors (SEN1xxx)
| Code | Enum | Description |
|---|---|---|
SEN1001 | INVALID_CONFIG | The provided configuration is malformed or missing required fields |
SEN1002 | MISSING_API_KEY | LLM provider API key not found in config or environment |
SEN1003 | INVALID_POLICY | Policy configuration is invalid (e.g., negative limits) |
SEN1004 | INVALID_RPC_ENDPOINT | RPC endpoint URL is malformed or unreachable |
Prompt Guard Errors (SEN2xxx)
| Code | Enum | Description |
|---|---|---|
SEN2001 | SCAN_FAILED | The scan operation failed unexpectedly |
SEN2002 | LLM_TIMEOUT | LLM call exceeded the configured timeoutMs |
SEN2003 | LLM_ERROR | LLM API returned an error response |
SEN2004 | RULE_LOAD_FAILED | Failed to load rule packs from disk |
SEN2005 | RULE_PARSE_ERROR | Rule pack YAML could not be parsed |
Execution Sandbox Errors (SEN3xxx)
| Code | Enum | Description |
|---|---|---|
SEN3001 | SIMULATION_FAILED | Transaction simulation failed unexpectedly |
SEN3002 | RPC_ERROR | Solana RPC returned an error response |
SEN3003 | RPC_TIMEOUT | RPC call exceeded the timeout |
SEN3004 | RPC_BLOCKHASH_EXPIRED | Transaction's recent blockhash has expired |
SEN3005 | POLICY_CHECK_FAILED | Policy enforcement encountered an internal error |
Spending Tracker Errors (SEN4xxx)
| Code | Enum | Description |
|---|---|---|
SEN4001 | SPENDING_LIMIT_EXCEEDED | Proposed spend would exceed configured limits |
SEN4002 | SPENDING_TRACKER_ERROR | Internal error in the spending tracker |
General Errors (SEN5xxx)
| Code | Enum | Description |
|---|---|---|
SEN5001 | UNKNOWN_ERROR | An unexpected error with no matching category |
SEN5002 | NOT_INITIALIZED | A component method was called before initialization |
SEN5003 | ALREADY_INITIALIZED | Initialization was attempted on an already-initialized component |
Error Handling Patterns
Distinguish Sentinel errors from other errors
typescript
import { SentinelError, SentinelErrorCode } from '@sentinel-sdk/core';
try {
const result = await sentinel.evaluateTransaction(tx);
} catch (err) {
if (err instanceof SentinelError) {
switch (err.code) {
case SentinelErrorCode.NOT_INITIALIZED:
// ExecutionSandbox not configured
break;
case SentinelErrorCode.RPC_ERROR:
// Solana RPC issue — retry or fallback
break;
default:
// Other Sentinel error
}
} else {
// Non-Sentinel error
throw err;
}
}
Using error codes as string values
typescript
// Error code strings are stable across versions
if (err.code === 'SEN5002') {
// NOT_INITIALIZED
}
// Prefer enum members in TypeScript for type safety
if (err.code === SentinelErrorCode.NOT_INITIALIZED) {
// ...
}
execute() never throws
Sentinel.execute() catches all internal errors and returns a blocked ExecutionResult. The only methods that throw SentinelError are scanInput() and evaluateTransaction(), and only for the NOT_INITIALIZED case (when the component wasn't configured).