#[non_exhaustive]pub enum FetchError {
NotEligible {
source_key: String,
},
NoOaAvailable,
NotFound {
hint: String,
},
Ambiguous {
hint: String,
},
Http(HttpError),
Log(LogError),
InvalidRef(RefParseError),
SourceSchema {
hint: String,
},
TooManyRefs {
got: usize,
max: usize,
},
TextUnavailable {
arxiv_id: ArxivId,
},
SourceUnavailable {
arxiv_id: ArxivId,
kind: &'static str,
},
}Expand description
Errors returned by Source::fetch.
At the public CLI / MCP boundary, every variant collapses to an
crate::ErrorCode via the From<FetchError> impl below — mirroring
the RefParseError → crate::ErrorCode::InvalidRef collapse from
PR #55.
Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
NotEligible
The source does not handle the given ref under the runtime
capability profile (covers both can_serve = false outcomes and
runtime denials raised inside fetch).
NoOaAvailable
Tier 1 sources reported no OA URL for this ref.
NotFound
A metadata source authoritatively reported that the identifier does
not exist — distinct from a transport failure. Surfaces as
crate::ErrorCode::NotFound. Used for sources whose
“absent” signal is NOT an HTTP 404/410 (e.g. the arXiv Atom API
returns HTTP 200 with an empty <feed> for an unknown id).
Ambiguous
A name filter (author / venue / publisher) matched MORE than one
OpenAlex entity with no clear winner. Carries a candidate listing
so the caller can narrow the name (or pass an explicit id).
Collapses to crate::ErrorCode::Ambiguous (wire "AMBIGUOUS") —
distinct from NotFound so an agent narrows rather than gives up.
Used by crate::discovery.
Http(HttpError)
Underlying HTTP / network failure. See HttpError.
Log(LogError)
Provenance log write failed. Per docs/SECURITY.md §1.8 this is a
fail-closed signal; the surrounding fetch MUST be aborted.
InvalidRef(RefParseError)
Ref re-parse / validation failed inside the source (e.g. when a source receives a borrowed string from upstream and re-validates).
SourceSchema
Source-side schema mismatch (unexpected JSON shape, missing
required field). Surfaces to crate::ErrorCode::InternalError
at the public boundary.
TooManyRefs
Batch orchestrator received more refs than
crate::MAX_BATCH_REFS. Surfaced to the MCP doiget_batch_fetch
tool as ErrorCode::InvalidRef (closest closed-set fit — the
request shape itself is invalid; no denial_context channel
applies). Slice 2 / docs/MCP_TOOLS.md §1.
Fields
max: usizeThe hard cap (crate::MAX_BATCH_REFS).
A source returned a successful response that contained no usable
representation of the requested kind — currently doiget text’s
ar5iv leg returning a 200 with no extractable prose (the paper was
never converted to HTML). The identifier is valid; only this one
representation is missing. Surfaces as
crate::ErrorCode::TextUnavailable so an agent fetches the PDF
instead of concluding the reference is wrong (issue #302) — NOT
Self::NotFound, which means the id itself does not exist.
A source returned a successful response that contained no file of the
requested kind for doiget source — a PDF-only / single-file
submission (no multi-file bundle), or --figures-only on a submission
with no image files. The identifier is valid; only the bundle / figure
representation is absent. Surfaces as
crate::ErrorCode::TextUnavailable (same “this representation is
missing; the PDF may be fetchable” class as Self::TextUnavailable),
but as a DISTINCT variant so the message is not ar5iv-specific
(issue #343 / ADR-0034; PR review).
Trait Implementations§
Source§impl Debug for FetchError
impl Debug for FetchError
Source§impl Display for FetchError
impl Display for FetchError
Source§impl Error for FetchError
impl Error for FetchError
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()
Source§impl From<&FetchError> for ErrorCode
Borrow-form of the collapse above, so a caller that still needs the
error for its Display message / denial_context side-channel
(notably the CLI human-persona renderer, issue #119) can obtain the
closed code without consuming it. The owned impl delegates here so
the mapping table lives in exactly one place.
impl From<&FetchError> for ErrorCode
Borrow-form of the collapse above, so a caller that still needs the
error for its Display message / denial_context side-channel
(notably the CLI human-persona renderer, issue #119) can obtain the
closed code without consuming it. The owned impl delegates here so
the mapping table lives in exactly one place.
Source§fn from(e: &FetchError) -> ErrorCode
fn from(e: &FetchError) -> ErrorCode
Source§impl From<&FetchError> for Option<DenialContext>
Map a FetchError reference to the structured crate::DenialContext
channel introduced by ADR-0023 §4.
impl From<&FetchError> for Option<DenialContext>
Map a FetchError reference to the structured crate::DenialContext
channel introduced by ADR-0023 §4.
&FetchError (rather than FetchError) so the orchestrator can
produce the structured side-channel without consuming the error it
still needs for error.message and the From<FetchError> for ErrorCode collapse above. The Http arm delegates to the
From<&HttpError> for Option<DenialContext> impl in crate::http.
Source§fn from(e: &FetchError) -> Self
fn from(e: &FetchError) -> Self
Source§impl From<FetchError> for ErrorCode
Map FetchError to the closed crate::ErrorCode set surfaced at
the public CLI / MCP boundary. Mirrors the
From<RefParseError> for ErrorCode collapse from PR #55.
impl From<FetchError> for ErrorCode
Map FetchError to the closed crate::ErrorCode set surfaced at
the public CLI / MCP boundary. Mirrors the
From<RefParseError> for ErrorCode collapse from PR #55.