1use std::{path::PathBuf, process::ExitStatus, time::Duration};
2
3use thiserror::Error;
4
5#[derive(Debug, Error)]
6pub enum ClaudeCodeError {
7 #[error("claude binary not found")]
8 MissingBinary,
9 #[error("failed to spawn claude process (binary={binary:?}): {source}")]
10 Spawn {
11 binary: PathBuf,
12 source: std::io::Error,
13 },
14 #[error("claude process timed out after {timeout:?}")]
15 Timeout { timeout: Duration },
16 #[error("failed waiting for claude process: {0}")]
17 Wait(std::io::Error),
18 #[error("failed reading stdout: {0}")]
19 StdoutRead(std::io::Error),
20 #[error("failed reading stderr: {0}")]
21 StderrRead(std::io::Error),
22 #[error("failed writing stdin: {0}")]
23 StdinWrite(std::io::Error),
24 #[error("internal error: missing stdout pipe")]
25 MissingStdout,
26 #[error("internal error: missing stderr pipe")]
27 MissingStderr,
28 #[error("internal error: join failure: {0}")]
29 Join(String),
30 #[error("request is invalid: {0}")]
31 InvalidRequest(String),
32 #[error("claude returned non-zero exit status: {status}")]
33 NonZeroExit { status: ExitStatus },
34 #[error("failed to parse JSON output: {0}")]
35 JsonParse(#[from] serde_json::Error),
36 #[error("failed to prepare CLAUDE_HOME directory `{path}`: {source}")]
37 PrepareClaudeHome {
38 path: PathBuf,
39 source: std::io::Error,
40 },
41 #[error("failed seeding Claude home (io) `{path}`: {source}")]
42 ClaudeHomeSeedIo {
43 path: PathBuf,
44 source: std::io::Error,
45 },
46 #[error("failed seeding Claude home: copy `{from}` -> `{to}`: {error}")]
47 ClaudeHomeSeedCopy {
48 from: PathBuf,
49 to: PathBuf,
50 error: std::io::Error,
51 },
52 #[error("claude home prepare failed: {0}")]
53 ClaudeHomePrepareFailed(String),
54 #[error("claude home seed failed: {0}")]
55 ClaudeHomeSeedFailed(String),
56}
57
58#[derive(Debug, Error, Clone)]
59#[error("stream-json line {line_number}: {message}")]
60pub struct StreamJsonLineError {
61 pub line_number: usize,
62 pub message: String,
63}