Skip to main content

Error

Enum Error 

Source
pub enum Error {
Show 16 variants NotFound, PermissionDenied, NoFilesystem, Unavailable, Foreign, Damaged, Failed, Unreachable, Busy, OutcomeUnknown, PeerDied, Malformed, Cancelled, Revoked, BufferTooSmall, InvalidInput,
}
Expand description

Everything a Godspeed operation can fail with.

Deliberately small. Each variant exists because a caller would do something DIFFERENT about it; a distinction nobody would act on belongs in a log line, not in a type.

Variants§

§

NotFound

No such file or directory. The service is healthy; the path is not there.

§

PermissionDenied

The operation needs a right this capability does not carry (§7.3 non-escalation). Asking again cannot help: rights never widen.

§

NoFilesystem

The volume is not mounted, or holds no GodspeedOS filesystem.

§

Unavailable

The storage is present but unreadable. Data may still be intact, so this is NOT an invitation to reformat.

§

Foreign

The disk holds a foreign partition table. Refused deliberately rather than overwritten.

§

Damaged

The file is there, and a block of it failed its checksum or could not be read: it is DAMAGED, not missing. drives scrub names every such block. fs answered this as “not found” until 2026-10-10 (backlog/fixed/80 V2).

§

Failed

The service tried and failed, and said so. A real failure with a real answer behind it.

§

Unreachable

The request never left this task: the peer’s capability is stale because it restarted (§14.2), or its name does not currently resolve. Nothing happened. Retrying after reacquiring the peer by name reaches the fresh instance, which crate::call::request_within already does for you once - for a send that never left, and for nothing else. A request that was delivered is never re-sent (Error::OutcomeUnknown, Error::PeerDied).

§

Busy

The peer is alive and its queue is full. Nothing happened. Congestion is transient by definition: pace and retry, and do not go looking for a peer that never went anywhere.

§

OutcomeUnknown

The deadline passed with no reply. The operation may have completed. The peer may be slow, or may be wedged. (A peer that DIED holding the request is Error::PeerDied on the CallDeadline path, crate::call::request_within; only paths that wait with a plain timed receive, such as crate::call::request_within_notice with a callback, report a death here too, because no ReplyDead reaches them.) This is the one failure you must not paper over: for anything that changes state, report it or re-read the truth, never re-send.

§

PeerDied

The request ARRIVED and the service died before answering it (the kernel’s ReplyDead, CLAUDE.md 8.6). The operation may have completed, exactly as with Error::OutcomeUnknown, so this is not safe to re-send blindly either.

It is its own variant because the caller does two things differently. It does not wait out a deadline or call the peer “silent” - the peer is gone, and saying it was slow sends an operator after the wrong fault. And it REACQUIRES before anything else, because the instance it asked no longer exists. For an operation that is safe to repeat - a read, a block transfer of the same sector - reacquire and ask again; that was what callers did before this variant existed, and now they say so.

§

Malformed

A reply came back that this library could not parse: too short, wrong tag, or a status byte outside the protocol. A bug somewhere, not a condition to handle - but it is reported rather than guessed past, because guessing is how a wrong byte index becomes a wrong answer.

§

Cancelled

The caller stopped waiting - a person pressed q, or the program gave up on purpose.

Not a fault, and the distinction is load-bearing: services/shell says it plainly, that “the user’s own q is NOT a fault - reporting it as one teaches the operator to distrust the error line, which is the thing they most need to trust”. A cancelled operation should be reported as cancelled, never as a failure.

It is still not safe to retry blindly. The request may already have been delivered and acted on; cancelling only means this caller stopped listening.

§

Revoked

The capability is no longer valid: whatever issued it revoked it, or died and was replaced (7.5 - a generation bump invalidates every outstanding cap).

The kernel refused this before the owning service was reached, so nothing happened and nothing was asked of anyone. Distinct from Error::Unreachable on purpose: the service is very likely up and well. Reporting this as “could not be reached” sends an operator to check a service that is running perfectly.

retry_is_safe is false here, and for the less obvious of its two reasons: a repeat cannot double-apply anything (the kernel refused before routing), but it can never succeed either, and a caller looping on that predicate would spin forever.

Re-open the resource - and remember that a capability obtained from a service’s PREVIOUS instance is stale even after you reacquire that service by name (14.3).

§

BufferTooSmall

The caller’s buffer is too small for the answer. Nothing was consumed; call again with room.

§

InvalidInput

The request could not be built: a path longer than the protocol allows, or a payload past the message ceiling. It was never sent.

Implementations§

Source§

impl Error

Source

pub fn retry_is_safe(self) -> bool

May I simply send this again?

true only when the request provably never reached the service, so a retry is the same operation rather than a second one. false for OutcomeUnknown even though a retry might work, because “might” is not good enough when the first attempt may already have committed.

For a read-only operation the caller may retry regardless; this is about what the LIBRARY can promise without knowing what the request was.

Source

pub fn service_answered(self) -> bool

true when the service answered. Distinguishes “no” from “no answer”, which is the coarse version of the distinction above and often the only one a caller needs.

Source

pub fn as_str(self) -> &'static str

A short, stable, human-readable phrase. Present tense, no trailing punctuation, no leading capital, so it drops into a sentence a utility is already building.

Trait Implementations§

Source§

impl Clone for Error

Source§

fn clone(&self) -> Error

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Error

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl PartialEq for Error

Source§

fn eq(&self, other: &Error) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Copy for Error

Source§

impl Eq for Error

Source§

impl StructuralPartialEq for Error

Auto Trait Implementations§

§

impl Freeze for Error

§

impl RefUnwindSafe for Error

§

impl Send for Error

§

impl Sync for Error

§

impl Unpin for Error

§

impl UnsafeUnpin for Error

§

impl UnwindSafe for Error

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.