#[non_exhaustive]pub enum Error {
Show 20 variants
VendoredContract {
surface: &'static str,
},
ContractOperation {
operation: String,
},
ContractParameter {
operation: String,
parameter: String,
},
ContractPathParameter {
operation: String,
parameter: String,
},
ContractRequiredParameter {
operation: String,
parameter: String,
location: &'static str,
},
ContractBody {
operation: String,
detail: &'static str,
},
Contract {
detail: &'static str,
},
SpecPath {
path: String,
},
Method {
method: String,
},
UnknownCassette {
name: String,
},
UnknownMethod {
cassette: String,
method: String,
},
Url {
source: ParseError,
},
NotABase,
Transport {
source: TransportError,
},
ClientInit,
ApiStatus {
status: u16,
endpoint: String,
body: String,
},
Decode {
source: Error,
},
BodyFile {
path: String,
source: Error,
},
InvalidBody {
source: Error,
},
RenderBody {
source: Error,
},
}Expand description
Anything that can go wrong driving a tapes API call.
#[snafu(module)] puts the generated context selectors in a nested error
module rather than at this module’s root: the selectors are construction
detail, and a consumer matches on the variants.
Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
VendoredContract
The contract embedded in this build did not parse, or reduced to nothing. Only reachable from a build whose vendored document is corrupt — this crate’s own tests fail before such a build ships.
ContractOperation
A caller named an operation the contract does not have. A build defect wherever the coverage gate runs, which is the point of the gate.
ContractParameter
A caller tried to send a parameter the contract does not declare on that operation. Refused rather than sent: an undeclared parameter is exactly the drift a vendored contract exists to catch, and a server that ignores an unknown query parameter would hide it.
ContractPathParameter
A caller had no value for a path parameter the operation requires, so
no URL can be built — the substitution would leave a literal {id}
segment addressing nothing.
ContractRequiredParameter
A caller had no value for a query or header parameter the contract marks required.
A missing path parameter cannot produce a URL at all, so it was always refused; a missing required query parameter produces a URL that is perfectly well-formed and still not a request the contract describes. The server answers it with a 400 whose wording is its own, which is a worse error later instead of a precise one now — and on an operation whose filter is what scopes the response, a client that guessed wrong about requiredness would be asking a different question than it thinks.
Fields
ContractBody
A caller’s request body disagrees with what the operation declares.
Both directions are refusals, and the reason is the same: a body-shaped
mismatch is invisible on the wire. An operation whose requestBody is
required, called without one, reaches the server as a syntactically
fine request that means nothing; a body sent to an operation that
declares none is dropped by whatever is in front of the handler. Either
way the call site looks correct.
Fields
Contract
The server’s response shape changed out from under this client.
SpecPath
Discovery named an OpenAPI document somewhere other than on this
server. Refused rather than followed: Url::join treats an absolute
URL as a replacement, so honouring it would fetch a spec from a host
the user never named.
Method
A spec described an operation with a verb that is not an HTTP method.
UnknownCassette
A cassette noun parsed but is not on the surface. Only reachable if the surface changed between building the parser and dispatching.
UnknownMethod
A cassette method parsed but is not on the cassette.
Url
A URL could not be built from the base and the contract’s path.
Fields
source: ParseErrorUnderlying parse failure.
NotABase
The base URL cannot carry a path (mailto:, data:), so no route can
be joined onto it.
Transport
The request could not be delivered.
The source is opaque on purpose. A transport may be an HTTP client, a local socket carrying opaque frames, or a test double, and this layer has no business naming any of their error types — that is precisely the coupling the seam exists to prevent. The source is rendered inline because a transport’s refusal is often the whole diagnosis — “the server answered with a redirect” is actionable, “could not reach the tapes API” alone is not — and a consumer that prints only the top-level error would otherwise lose it.
Fields
source: TransportErrorUnderlying transport failure.
ClientInit
The transport itself could not be constructed. Requests error out rather than fall back to a client with different (redirect-following) behavior.
ApiStatus
The server answered with a non-success status. The body is carried because every tapes error body names the offending parameter.
Fields
Decode
The response could not be decoded: it is not JSON, or it is JSON that is not the type the caller asked for.
The second half is unreachable for the untyped instantiation — every
JSON document is a serde_json::Value — so a decode failure on a
caller-chosen model is visible exactly where that choice was made.
BodyFile
--body @<path> could not be read.
InvalidBody
--body was not JSON. Checked before sending so the failure names the
quoting mistake rather than arriving as a cassette’s schema error.
RenderBody
The parsed body could not be re-rendered for sending. Only reachable if serde_json emits a value it cannot serialize back.
Trait Implementations§
Source§impl Error for Error
impl Error for Error
Source§fn description(&self) -> &str
fn description(&self) -> &str
use the Display impl or to_string()
Source§fn cause(&self) -> Option<&dyn Error>
fn cause(&self) -> Option<&dyn Error>
replaced by Error::source, which can support downcasting
Source§impl ErrorCompat for Error
impl ErrorCompat for Error
Source§fn iter_chain(&self) -> ChainCompat<'_, '_> ⓘwhere
Self: AsErrorSource,
fn iter_chain(&self) -> ChainCompat<'_, '_> ⓘwhere
Self: AsErrorSource,
Error::source. Read more