Skip to main content

Error

Enum Error 

Source
pub enum Error {
Show 21 variants PktLine(Error), Io(Error), Store(Error), Pack(String), ObjectMissing { oid: ObjectId, context: Option<String>, }, CorruptObject { oid: ObjectId, reason: String, }, Protocol(String), OverCeiling(String), Refused(String), ObjectFormatMismatch { ours: &'static str, theirs: String, }, RemoteObjectFormat { ours: &'static str, theirs: String, }, Remote(String), UnknownArgument { command: &'static str, argument: String, }, UnsupportedFilter { spec: String, reason: &'static str, }, WantNotAdvertised { oid: ObjectId, }, UnexpectedEof(&'static str), WalkBudget { limit: usize, }, WalkTooLarge { held: usize, limit: usize, }, WalkPoolFull { wanted: usize, in_flight: usize, limit: usize, }, RequestTooLarge { limit: usize, what: &'static str, }, ObjectTooLarge { oid: ObjectId, size: u64, limit: u64, },
}
Expand description

Everything gunnar-wire can fail with.

Variants§

§

PktLine(Error)

The framing layer rejected a line.

§

Io(Error)

The transport failed.

§

Store(Error)

The storage layer failed.

§

Pack(String)

Writing or indexing a packfile failed.

A message, not another crate’s error type. It was #[from] gunnar_pack::Error until 2026-08-10, and that one #[from] was the last thing making gunnar-pack — and behind it gix-pack and ten more gix crates — a normal dependency of a crate that has not called a pack writer or a pack indexer since the engine seam landed. See crate::pack. Nothing under src/ constructs this; a packfile is somebody else’s to write, and the somebody is an engine behind the contract.

§

ObjectMissing

An object the protocol requires is not in the repository.

On the serving side this means a corrupt repository; on the receiving side it means a push whose connectivity does not close.

Fields

§oid: ObjectId

The object that could not be found.

§context: Option<String>

What was being done when it was needed.

§

CorruptObject

An object could not be parsed as the kind it claims to be.

Fields

§oid: ObjectId

The object that would not decode.

§reason: String

Why not.

§

Protocol(String)

The peer sent something the protocol does not allow here.

§

OverCeiling(String)

A fetch’s packfile passed the byte ceiling it was held to (FetchPack::with_ceiling) and was cut mid-transfer; the ingest was handed at most the ceiling and one byte, and nothing was stored. The text is the ceiling’s own refusal, verbatim — the sentence whoever set it composed, the same one a push past the same ceiling is told — never “the pack is corrupt”, which is what the indexer would have made of the cut stream.

§

Refused(String)

A policy refused the pushed pack before any of it was kept — the encrypted-repository gate, run on the pack in quarantine (gunnar-server encrypted_quarantine). Its sentence is the client’s, word for word: it names the file and the fix, and it reveals nothing the pusher did not send.

§

ObjectFormatMismatch

The peer named a hash algorithm this repository does not use.

Getting this wrong silently is the documented, session-costing bug of Object-format negotiation: a sha1 answer to a sha256 repository produces an empty response rather than an error, so it is made loud here.

Fields

§ours: &'static str

The repository’s actual format name.

§theirs: String

What the client asked for.

§

RemoteObjectFormat

The same mismatch as Error::ObjectFormatMismatch, from the client’s chair.

Two variants and not one because the sentence is the point. The other says “the client asked for X, but this repository is Y”, which is what a server tells a client; an operator reading that about their own mirror would go looking for a client that does not exist. This one names the remote as the remote.

The failure it prevents is object-format negotiation’s, unchanged: a sha1 client against a sha256 remote does not error, it negotiates an empty answer, so fetch_pack refuses at the advertisement rather than reporting a successful fetch of nothing.

Fields

§ours: &'static str

The local repository’s format name.

§theirs: String

What the remote said.

§

Remote(String)

The remote reported a fatal condition on sideband 3.

Verbatim, because it is the only thing the remote will ever say about why: band 3 is how upload-pack reports “repository not found” or “want is not a valid object” once a sideband is open, and a client that turned it into “the transfer failed” would throw away the whole diagnosis.

§

UnknownArgument

An argument that is not in this command’s argument table.

Fields

§command: &'static str

Which v2 command was being parsed.

§argument: String

The offending argument line.

§

UnsupportedFilter

A filter specification gunnar does not implement.

Fields

§spec: String

The specification as sent.

§reason: &'static str

Why it was refused.

§

WantNotAdvertised

A want naming something that is not an advertised reference tip.

Serving arbitrary object ids leaks objects that are not reachable from any reference, which is how “deleted” branches stay fetchable.

Fields

§oid: ObjectId

The object the client asked for.

§

UnexpectedEof(&'static str)

The peer hung up in the middle of a message.

§

WalkBudget

A traversal ran past its object budget.

A budget rather than an unbounded walk because the object graph comes from the network: a crafted repository must not be able to make the server allocate without limit.

Fields

§limit: usize

The budget that was hit.

§

WalkTooLarge

A traversal would have held more object bookkeeping than Limits::walk_bytes allows.

The bytes are the ids the walk is holding live, charged at WALK_BYTES_PER_OBJECT, which is a measured rate and not a struct size. Nothing is inflated to arrive at it: charging a walk by decompressing what it walks over is the defect that cost gix-odb half its read-side CPU.

Fields

§held: usize

What the walk would have been holding.

§limit: usize

The ceiling that was hit.

§

WalkPoolFull

The server-wide WalkPool had no room left.

Not the same refusal as Error::WalkTooLarge, and telling them apart is the point: this one says the request was reasonable and the machine is full, so a client that waits and retries will get served. The other says this request will never fit.

Fields

§wanted: usize

What this walk asked the pool for.

§in_flight: usize

What the pool had already handed out.

§limit: usize

The pool’s ceiling.

§

RequestTooLarge

The peer’s request would have cost more memory than Limits::request_bytes allows.

The budget is spent as the request is framed, so this is raised with the ceiling’s worth of bytes held and not a byte more. A client that sends have lines forever is refused here rather than at the point where the allocator gives up.

Fields

§limit: usize

The ceiling that was hit.

§what: &'static str

Which part of the request overspent.

§

ObjectTooLarge

An object is larger than Limits::object_bytes allows gunnar to materialise while serving a fetch.

Read from the object’s header, before its content, so the ceiling refuses the transfer rather than reporting on an allocation that has already happened. Refused rather than skipped: a pack missing an object its trees name is a corrupt clone, which is worse than no clone.

Fields

§oid: ObjectId

The object that is too big.

§size: u64

Its size, from its header.

§limit: u64

The ceiling that was hit.

Implementations§

Source§

impl Error

Source

pub fn pack(what: impl Display) -> Self

A packfile could not be written or indexed.

pub rather than pub(crate) because the only callers are outside this crate: a PackIngest is caller-supplied, so whoever indexes the pack is also whoever names why it would not index. See Error::Pack.

Source

pub fn client_message(&self) -> String

The one-line text this error is worth sending to a client, without leaking server paths or internals.

§Why this is not to_string()

It was, and the doc comment above it made the claim anyway. Variants of this enum are #[error(transparent)] over another crate’s error — Error::Io and Error::Store, and until 2026-08-10 Error::Pack as well — so whatever the storage layer said went out verbatim. gunnar_store::Error::StoreLocked renders the absolute path of the lock file, and crate::receive_pack puts client_message() straight into the unpack line of a push report, so git push printed a server path to whoever pushed. gunnar-ssh and gunnar-lfs both redact at this seam already (DispatchError::client_message, gunnar_lfs::Error::client_message); this crate was the one that did not.

Everything else stays verbatim, and that is deliberate: an oid, a filter spec, an argument name and a byte ceiling are either the client’s own words or facts about the protocol, and they are what makes a refusal actionable without a server login. git’s own upload-pack tells a client which object it wanted and could not have.

The unredacted text is still what the server logs — see git.upload_pack.failed, which carries %err and not this.

Trait Implementations§

Source§

impl Debug for Error

Source§

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

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

impl Display for Error

Source§

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

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

impl Error for Error

Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0:

use the Display impl or to_string()

1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0:

replaced by Error::source, which can support downcasting

Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl From<Error> for Error

Source§

fn from(source: Error) -> Self

Converts to this type from the input type.
Source§

impl From<Error> for Error

Source§

fn from(source: Error) -> Self

Converts to this type from the input type.
Source§

impl From<Error> for Error

Source§

fn from(source: Error) -> Self

Converts to this type from the input type.

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> 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> ErrorExt for T
where T: Error + Send + Sync + 'static,

Source§

fn raise(self) -> Exn<Self>
where Self: Sized,

Raise this error as a new exception.
Source§

fn and_raise<T>(self, context: T) -> Exn<T>
where T: Error + Send + Sync + 'static, Self: Sized,

Raise this error as a child of a new exception with the given context error. Read more
Source§

fn raise_erased(self) -> Exn
where Self: Sized,

Raise this error as a new exception, with type erasure.
Source§

fn raise_all<T, I>(self, sources: I) -> Exn<Self>
where Self: Sized, T: Error + Send + Sync + 'static, I: IntoIterator, <I as IntoIterator>::Item: Into<Exn<T>>,

Raise this error as a new exception, with sources as causes.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

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

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

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.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more