SpiceError Types
Complete reference for all error types in the Spice Framework error hierarchy.
Error Hierarchyβ
sealed class SpiceError {
abstract val message: String
abstract val code: String
open val cause: Throwable? = null
open val context: Map<String, Any> = emptyMap()
val timestamp: Long
}
All errors include:
- message: Human-readable error description
- code: Machine-readable error code (e.g., "AGENT_ERROR")
- cause: Optional underlying exception
- context: Additional debugging information
- timestamp: When the error occurred
Error Typesβ
AgentErrorβ
Errors related to agent operations and processing.
data class AgentError(
override val message: String,
override val cause: Throwable? = null,
val agentId: String? = null,
override val context: Map<String, Any> = emptyMap()
) : SpiceError()
When to use:
- Agent fails to process a communication
- Agent initialization fails
- Agent state is invalid
Example:
SpiceError.agentError(
message = "Failed to process communication",
agentId = "claude-assistant",
cause = originalException
).withContext(
"comm_id" to commId,
"agent_state" to "processing"
)
CommErrorβ
Errors related to communication (Comm) operations.
data class CommError(
override val message: String,
val comm: Comm? = null,
override val cause: Throwable? = null,
override val context: Map<String, Any> = emptyMap()
) : SpiceError()
When to use:
- Invalid communication format
- Communication routing fails
- Message delivery fails
Example:
SpiceError.commError(
message = "Failed to deliver message",
comm = originalComm
).withContext(
"recipient" to comm.to,
"retry_count" to 3
)
ToolErrorβ
Errors related to tool execution.
data class ToolError(
override val message: String,
val toolName: String,
override val cause: Throwable? = null,
override val context: Map<String, Any> = emptyMap()
) : SpiceError()
When to use:
- Tool execution fails
- Tool not found
- Invalid tool parameters
Example:
SpiceError.toolError(
message = "Tool execution failed",
toolName = "calculator"
).withContext(
"parameters" to params,
"execution_time_ms" to executionTime
)
ConfigurationErrorβ
Errors related to invalid or missing configuration.
data class ConfigurationError(
override val message: String,
val field: String? = null,
override val cause: Throwable? = null,
override val context: Map<String, Any> = emptyMap()
) : SpiceError()
When to use:
- Required configuration missing
- Invalid configuration value
- Configuration format error
Example:
SpiceError.configError(
message = "API key is required",
field = "apiKey"
).withContext(
"provider" to "openai",
"config_source" to "environment"
)
ValidationErrorβ
Errors related to input validation.
data class ValidationError(
override val message: String,
val field: String? = null,
val expectedType: String? = null,
val actualValue: Any? = null,
override val context: Map<String, Any> = emptyMap()
) : SpiceError()
When to use:
- Input doesn't match expected format
- Required field missing
- Type mismatch
Example:
SpiceError.validationError(
message = "Invalid email format",
field = "email",
expectedType = "email",
actualValue = userInput
).withContext(
"validation_rule" to "RFC5322",
"form_id" to "user_registration"
)
NetworkErrorβ
Errors related to network operations.
data class NetworkError(
override val message: String,
val statusCode: Int? = null,
val endpoint: String? = null,
override val cause: Throwable? = null,
override val context: Map<String, Any> = emptyMap()
) : SpiceError()
When to use:
- HTTP request fails
- Network connectivity issues
- API returns error status
Example:
SpiceError.networkError(
message = "Failed to fetch user data",
statusCode = 404,
endpoint = "/api/users/123"
).withContext(
"method" to "GET",
"retry_attempt" to 2
)
TimeoutErrorβ
Errors related to operation timeouts.
data class TimeoutError(
override val message: String,
val timeoutMs: Long? = null,
val operation: String? = null,
override val context: Map<String, Any> = emptyMap()
) : SpiceError()
When to use:
- Operation exceeds time limit
- Agent doesn't respond in time
- External service timeout
Example:
SpiceError.timeoutError(
message = "Agent response timeout",
timeoutMs = 30000,
operation = "agent.processComm"
).withContext(
"agent_id" to "claude",
"comm_id" to commId
)
AuthenticationErrorβ
Errors related to authentication and authorization.
data class AuthenticationError(
override val message: String,
val provider: String? = null,
override val cause: Throwable? = null,
override val context: Map<String, Any> = emptyMap()
) : SpiceError()
When to use:
- Invalid API key
- Expired token
- Insufficient permissions
Example:
SpiceError.authError(
message = "Invalid API key",
provider = "openai"
).withContext(
"key_prefix" to apiKey.take(8),
"endpoint" to "/v1/chat/completions"
)
RateLimitErrorβ
Errors related to rate limiting.
data class RateLimitError(
override val message: String,
val retryAfterMs: Long? = null,
val limitType: String? = null,
override val context: Map<String, Any> = emptyMap()
) : SpiceError()
When to use:
- API rate limit exceeded
- Too many requests
- Quota exhausted
Example:
SpiceError.rateLimitError(
message = "Rate limit exceeded",
retryAfterMs = 60000,
limitType = "requests_per_minute"
).withContext(
"limit" to 60,
"current_count" to 61,
"window_start" to windowStart
)
SerializationErrorβ
Errors related to serialization and deserialization.
data class SerializationError(
override val message: String,
val format: String? = null,
override val cause: Throwable? = null,
override val context: Map<String, Any> = emptyMap()
) : SpiceError()
When to use:
- JSON parsing fails
- Invalid data format
- Type conversion error
Example:
SpiceError.SerializationError(
message = "Failed to parse JSON response",
format = "json",
cause = jsonException
).withContext(
"response_preview" to response.take(100),
"expected_schema" to "User"
)
UnknownErrorβ
Fallback for unexpected errors.
data class UnknownError(
override val message: String,
override val cause: Throwable? = null,
override val context: Map<String, Any> = emptyMap()
) : SpiceError()
When to use:
- Unexpected exception
- Error doesn't fit other categories
- Fallback error handling
Example:
SpiceError.UnknownError(
message = "Unexpected error occurred",
cause = exception
).withContext(
"operation" to "data_processing",
"exception_type" to exception::class.simpleName
)
Working with Errorsβ
Adding Contextβ
Add debugging information to any error:
val error = SpiceError.agentError("Processing failed")
.withContext(
"agent_id" to "claude",
"input_length" to input.length,
"timestamp" to System.currentTimeMillis()
)
Converting to Exceptionβ
Convert SpiceError to an exception for throwing:
val error = SpiceError.networkError("Connection failed")
throw error.toException() // Throws SpiceException
Mapping Exceptionsβ
Convert standard exceptions to SpiceError:
val error = SpiceError.fromException(throwable)
// Automatically maps:
// - IllegalArgumentException β ValidationError
// - IllegalStateException β ConfigurationError
// - UnknownHostException β NetworkError
// - SocketTimeoutException β TimeoutError
// - SerializationException β SerializationError
// - Others β UnknownError
Pattern Matchingβ
Handle different error types:
when (val error = result.error) {
is SpiceError.NetworkError -> {
if (error.statusCode == 503) {
// Service unavailable, retry
}
}
is SpiceError.RateLimitError -> {
delay(error.retryAfterMs ?: 1000)
retry()
}
is SpiceError.AuthenticationError -> {
// Re-authenticate
refreshToken()
}
is SpiceError.ValidationError -> {
// Show user-friendly error
showError("Invalid ${error.field}: ${error.message}")
}
else -> {
// Generic error handling
logger.error("Error: ${error.message}", error.cause)
}
}
Error Recovery Strategiesβ
Network Errorsβ
fun handleNetworkError(error: SpiceError.NetworkError): SpiceResult<Data> {
return when (error.statusCode) {
in 500..599 -> {
// Server error - retry
retryWithBackoff()
}
404 -> {
// Not found - use default
SpiceResult.success(Data.default())
}
401, 403 -> {
// Auth error - fail fast
SpiceResult.failure(error)
}
else -> {
// Other errors - try cache
loadFromCache().recoverWith { SpiceResult.failure(error) }
}
}
}
Rate Limit Errorsβ
suspend fun handleRateLimit(
error: SpiceError.RateLimitError,
operation: suspend () -> SpiceResult<T>
): SpiceResult<T> {
delay(error.retryAfterMs ?: 1000)
return operation()
}
Validation Errorsβ
fun handleValidationError(error: SpiceError.ValidationError): UserMessage {
return UserMessage(
field = error.field ?: "unknown",
message = when (error.field) {
"email" -> "Please enter a valid email address"
"password" -> "Password must be at least 8 characters"
else -> error.message
}
)
}
Best Practicesβ
1. Choose the Right Error Typeβ
// β
Good - Specific error type
SpiceError.validationError(
message = "Email is required",
field = "email"
)
// β Bad - Generic error
SpiceError.unknownError("Email is required")
2. Include Contextβ
// β
Good - Rich context
SpiceError.toolError("Execution failed", "calculator")
.withContext(
"parameters" to params,
"execution_time" to duration,
"memory_used" to memoryUsed
)
// β Bad - No context
SpiceError.toolError("Execution failed", "calculator")
3. Preserve Causeβ
// β
Good - Preserves stack trace
SpiceError.networkError(
message = "API call failed",
cause = ioException
)
// β Bad - Lost stack trace
SpiceError.networkError(
message = "API call failed: ${ioException.message}"
)
4. Use Descriptive Messagesβ
// β
Good - Clear and actionable
SpiceError.authError(
message = "API key is invalid or expired. Please check your credentials.",
provider = "openai"
)
// β Bad - Vague
SpiceError.authError("Auth failed")
Next Stepsβ
- SpiceResult Guide - Learn how to use SpiceResult
- Best Practices - Advanced error handling patterns