shopify_approver_opencode/
error.rs

1//! Error types for OpenCode client
2
3use thiserror::Error;
4
5/// Result type for OpenCode operations
6pub type Result<T> = std::result::Result<T, OpenCodeError>;
7
8/// Errors that can occur when communicating with OpenCode
9#[derive(Error, Debug)]
10pub enum OpenCodeError {
11    /// HTTP request failed
12    #[error("HTTP error: {0}")]
13    Http(#[from] reqwest::Error),
14
15    /// Failed to serialize/deserialize JSON
16    #[error("JSON error: {0}")]
17    Json(#[from] serde_json::Error),
18
19    /// Failed to package codebase
20    #[error("Packaging error: {0}")]
21    Packaging(String),
22
23    /// IO error during file operations
24    #[error("IO error: {0}")]
25    Io(#[from] std::io::Error),
26
27    /// OpenCode service returned an error
28    #[error("OpenCode error: {status} - {message}")]
29    ServiceError {
30        status: u16,
31        message: String,
32    },
33
34    /// Index not found
35    #[error("Index not found: {0}")]
36    IndexNotFound(String),
37
38    /// Index is still processing
39    #[error("Index is still processing: {0}")]
40    IndexPending(String),
41
42    /// Timeout waiting for indexing
43    #[error("Timeout waiting for indexing to complete")]
44    IndexingTimeout,
45
46    /// Invalid configuration
47    #[error("Invalid configuration: {0}")]
48    InvalidConfig(String),
49
50    /// Search returned no results
51    #[error("No results found for query: {0}")]
52    NoResults(String),
53
54    /// File not found in index
55    #[error("File not found in index: {0}")]
56    FileNotFound(String),
57}
58
59impl OpenCodeError {
60    /// Create a service error from status code and message
61    pub fn service_error(status: u16, message: impl Into<String>) -> Self {
62        Self::ServiceError {
63            status,
64            message: message.into(),
65        }
66    }
67
68    /// Check if error is retryable
69    pub fn is_retryable(&self) -> bool {
70        match self {
71            Self::Http(e) => e.is_timeout() || e.is_connect(),
72            Self::ServiceError { status, .. } => *status >= 500,
73            Self::IndexPending(_) => true,
74            _ => false,
75        }
76    }
77}