pub enum Error {
Io(Error),
State(Error),
Provider {
kind: ProviderErrorKind,
status: Option<u16>,
retry_after: Option<Duration>,
message: String,
},
Config(String),
Sandbox {
reason: String,
},
Refused {
act: String,
target: String,
rule: Option<String>,
layer: Option<String>,
},
Mcp {
server: String,
reason: String,
},
Resume {
reason: String,
},
}Expand description
Errors io-harness can return from a run.
The variants are separate because the response to each is separate — a refusal is not a malfunction, a bad checkpoint is not a bad key, and only one arm here is ever worth retrying. This is the match a caller writes around an entry point:
use io_harness::Error;
match failure {
// The policy said no. Nothing happened and nothing is broken: either
// widen the rule that refused it, or accept the refusal. The rule and
// layer are carried so the operator knows which line of config to edit.
Error::Refused { act, target, rule, layer } => format!(
"{act} {target} refused by {} in layer {}",
rule.unwrap_or_else(|| "the tier default".into()),
layer.unwrap_or_else(|| "-".into()),
),
// The checkpoint could not be honoured — newer format, missing run, or a
// run started under a policy this resume would have silently dropped.
// Never retried in a loop: re-resume the way the message names.
Error::Resume { reason } => format!("resume refused: {reason}"),
// Operator error, raised before the provider is called once. Fail the
// job; a second attempt reaches the same missing key or duplicate tool.
Error::Config(message) => format!("fix the configuration: {message}"),
// The tool server never came up. The run fails rather than quietly
// proceeding without a capability it was told it had.
Error::Mcp { server, reason } => format!("server {server} did not start: {reason}"),
// The gate never ran the code, as opposed to running it and failing it.
Error::Sandbox { reason } => format!("verification never executed: {reason}"),
// The one arm where another attempt is a real option — and only for some
// kinds; see `ProviderErrorKind::is_retryable`.
Error::Provider { kind, message, .. } if kind.is_retryable() => format!("retry: {message}"),
other => other.to_string(),
}Variants§
Io(Error)
A filesystem tool operation failed.
State(Error)
The state store (rusqlite) failed.
Provider
The provider request or its streamed response failed.
ProviderErrorKind is what a caller branches on; status and
retry_after are kept rather than folded into the message so a retry can
honour what the server actually said.
Fields
kind: ProviderErrorKindWhy the call failed, and whether retrying is worth it.
Config(String)
Configuration was missing or invalid (e.g. no API key).
Sandbox
The sandbox failed to start (e.g. the backend or the program could not be
spawned). Typed separately from Error::Io so a calling agent can tell
“the sandbox never ran the code” apart from “the code ran and failed”, and
adapt — one failed child does not take down its siblings or the tree.
Refused
The permission policy refused the action. Typed separately from
Error::Config so a refusal is distinguishable from a malfunction —
a verification that was refused is not a verification that ran and
failed, and the model is told the difference.
Fields
Mcp
An MCP server could not be reached or set up. Typed separately from
Error::Provider so a caller can tell “the model call failed” from
“the tool server the operator configured never came up” — the second is a
configuration problem, and the run fails on it rather than quietly
proceeding without a capability it was told it had.
Failures during a call — a timeout, a dead transport, a tool reporting its own error — are not this. They come back to the model as observations it can adapt to, like a refused path or a bad regex.
Resume
A durable run could not be resumed from its checkpoint — the checkpoint format is newer than this binary supports, the run row is missing or corrupt, or the run has already finished. Typed separately so a caller handles a bad-checkpoint resume as a recoverable error instead of a panic or a silent half-resume. A partially written (crashed mid-commit) step is never surfaced here: the transaction rolls it back, so resume always sees the prior consistent checkpoint, not a torn one.
Implementations§
Source§impl Error
impl Error
Sourcepub fn provider(kind: ProviderErrorKind, message: impl Into<String>) -> Self
pub fn provider(kind: ProviderErrorKind, message: impl Into<String>) -> Self
A provider failure of kind carrying no HTTP status — the request never
completed, or the response could not be read.
Sourcepub fn provider_transport(message: impl Into<String>) -> Self
pub fn provider_transport(message: impl Into<String>) -> Self
The request never completed: connection refused, DNS, TLS, a mid-stream byte error.
Sourcepub fn provider_malformed(message: impl Into<String>) -> Self
pub fn provider_malformed(message: impl Into<String>) -> Self
The response arrived and nothing in it could be read.
Sourcepub fn provider_status(
status: u16,
retry_after: Option<Duration>,
message: impl Into<String>,
) -> Self
pub fn provider_status( status: u16, retry_after: Option<Duration>, message: impl Into<String>, ) -> Self
A non-success HTTP status, with the kind derived once by
ProviderErrorKind::from_status so no provider can classify it
differently.
Trait Implementations§
Source§impl Error for Error
impl Error for Error
Source§fn source(&self) -> Option<&(dyn Error + 'static)>
fn source(&self) -> Option<&(dyn Error + 'static)>
1.0.0 · Source§fn description(&self) -> &str
fn description(&self) -> &str
use the Display impl or to_string()
Auto Trait Implementations§
impl !RefUnwindSafe for Error
impl !UnwindSafe for Error
impl Freeze for Error
impl Send for Error
impl Sync for Error
impl Unpin for Error
impl UnsafeUnpin for Error
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<T> Separable for Twhere
T: Display,
impl<T> Separable for Twhere
T: Display,
Source§fn separate_by_policy(&self, policy: SeparatorPolicy<'_>) -> String
fn separate_by_policy(&self, policy: SeparatorPolicy<'_>) -> String
SeparatorPolicy. Read moreSource§fn separate_with_commas(&self) -> String
fn separate_with_commas(&self) -> String
Source§fn separate_with_spaces(&self) -> String
fn separate_with_spaces(&self) -> String
Source§fn separate_with_dots(&self) -> String
fn separate_with_dots(&self) -> String
Source§fn separate_with_underscores(&self) -> String
fn separate_with_underscores(&self) -> String
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.