Skip to main content

zeph_acp/client/
error.rs

1// SPDX-FileCopyrightText: 2026 Andrei G <bug-ops>
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4use thiserror::Error;
5
6/// Step in the ACP handshake sequence at which a failure occurred.
7#[derive(Debug, Clone, PartialEq, Eq)]
8pub enum HandshakeStep {
9    /// The `initialize` request round-trip failed.
10    Initialize,
11    /// The `session/new` request round-trip failed.
12    NewSession,
13}
14
15impl std::fmt::Display for HandshakeStep {
16    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17        match self {
18            Self::Initialize => f.write_str("initialize"),
19            Self::NewSession => f.write_str("session/new"),
20        }
21    }
22}
23
24/// Errors returned by the ACP sub-agent client.
25#[derive(Debug, Error)]
26pub enum AcpClientError {
27    /// The command string was empty or could not be shell-split.
28    #[error("invalid command config: {0}")]
29    InvalidConfig(String),
30
31    /// The subprocess failed to spawn.
32    #[error("failed to spawn subprocess: {0}")]
33    Spawn(#[source] std::io::Error),
34
35    /// The ACP handshake failed at the named step.
36    #[error("handshake failed at {step}: {source}")]
37    Handshake {
38        /// Which handshake step failed.
39        step: HandshakeStep,
40        /// The underlying protocol error.
41        #[source]
42        source: agent_client_protocol::Error,
43    },
44
45    /// The prompt or notification could not be sent to the sub-agent.
46    #[error("failed to send to sub-agent: {0}")]
47    SendFailed(#[source] agent_client_protocol::Error),
48
49    /// A second command was sent while the driver was already servicing a read.
50    ///
51    /// The caller should wait for the in-flight operation to complete before retrying.
52    #[error("driver is busy servicing another read operation")]
53    DriverBusy,
54
55    /// The driver task exited unexpectedly before the operation could complete.
56    ///
57    /// This usually means the subprocess crashed or the transport was closed.
58    #[error("driver task exited unexpectedly")]
59    DriverDied,
60
61    /// The operation timed out.
62    #[error("operation timed out")]
63    Timeout,
64
65    /// The session was closed by a call to [`super::SubagentHandle::close`] or via
66    /// a [`super::SubagentCommand::Close`] command.
67    #[error("session is closed")]
68    Closed,
69
70    /// A cancel was requested and the sub-agent acknowledged it by returning a
71    /// `StopReason::Cancelled` update.
72    #[error("operation cancelled")]
73    Cancelled,
74
75    /// Underlying SDK/protocol error not covered by the variants above.
76    #[error("ACP SDK error: {0}")]
77    Sdk(#[source] agent_client_protocol::Error),
78}