use thiserror::Error;
#[derive(Debug, Error, Clone)]
#[error("{message}")]
pub struct OpencodeSDKError {
pub message: String,
}
impl OpencodeSDKError {
pub fn new(message: impl Into<String>) -> Self {
Self {
message: message.into(),
}
}
}
#[derive(Debug, Error, Clone)]
#[error("{message}")]
pub struct CLINotFoundError {
pub message: String,
pub cli_path: Option<String>,
}
impl CLINotFoundError {
pub fn new(message: impl Into<String>, cli_path: Option<String>) -> Self {
let base = message.into();
let message = match &cli_path {
Some(path) => format!("{base}: {path}"),
None => base,
};
Self { message, cli_path }
}
}
#[derive(Debug, Error, Clone)]
#[error("{message}")]
pub struct ProcessError {
pub message: String,
pub exit_code: Option<i32>,
pub output: Option<String>,
}
impl ProcessError {
pub fn new(message: impl Into<String>, exit_code: Option<i32>, output: Option<String>) -> Self {
let base = message.into();
let mut message = base;
if let Some(code) = exit_code {
message = format!("{message} (exit code: {code})");
}
if let Some(content) = &output {
if !content.trim().is_empty() {
message = format!("{message}\nOutput: {content}");
}
}
Self {
message,
exit_code,
output,
}
}
}
#[derive(Debug, Error, Clone)]
#[error("OpenCode API error: status {status}, body: {body}")]
pub struct ApiError {
pub status: u16,
pub body: String,
}
#[derive(Debug, Error)]
pub enum Error {
#[error(transparent)]
OpencodeSDK(#[from] OpencodeSDKError),
#[error(transparent)]
CLINotFound(#[from] CLINotFoundError),
#[error(transparent)]
Process(#[from] ProcessError),
#[error(transparent)]
Api(#[from] ApiError),
#[error(transparent)]
Io(#[from] std::io::Error),
#[error(transparent)]
Json(#[from] serde_json::Error),
#[error(transparent)]
Http(#[from] reqwest::Error),
#[error(transparent)]
InvalidHeaderValue(#[from] reqwest::header::InvalidHeaderValue),
#[error(transparent)]
InvalidHeaderName(#[from] reqwest::header::InvalidHeaderName),
#[error("Timeout waiting for server to start after {timeout_ms}ms")]
ServerStartupTimeout { timeout_ms: u64 },
#[error("Missing required path parameter: {0}")]
MissingPathParameter(String),
}
pub type Result<T> = std::result::Result<T, Error>;