pub enum SendraError {
Show 30 variants
Io {
path: PathBuf,
source: Error,
},
Parse {
path: PathBuf,
source: Error,
},
ParseStr(Error),
Serialize(Error),
SaveIo {
path: PathBuf,
source: Error,
},
InvalidHeader {
name: String,
reason: String,
},
Network {
url: String,
source: Error,
},
Timeout {
url: String,
timeout: Duration,
source: Error,
},
Client(Error),
RequestNotFound {
name: String,
available: Vec<String>,
},
NotACollection {
name: String,
},
InvalidCollection {
reason: String,
},
InvalidRequest {
reason: String,
},
BodyFileIo {
path: PathBuf,
source: Error,
},
ClientCertIo {
path: PathBuf,
source: Error,
},
ClientCertIncomplete {
which: &'static str,
},
ConfigIo {
path: PathBuf,
source: Error,
},
ConfigParse {
path: PathBuf,
source: Error,
},
CurrentDir(Error),
EnvIo {
path: PathBuf,
source: Error,
},
EnvParse {
path: PathBuf,
source: Error,
},
EnvSaveIo {
path: PathBuf,
source: Error,
},
InvalidEnvironment {
path: Option<PathBuf>,
reason: String,
},
VariableNotFound {
name: String,
available: Vec<String>,
environment: Option<PathBuf>,
captured: Vec<String>,
},
EnvVarNotSet {
name: String,
variable: String,
environment: Option<PathBuf>,
},
ScriptParse {
hook: Hook,
source: ParseError,
},
ScriptFailed {
hook: Hook,
message: String,
},
ScriptRequest {
reason: String,
},
OAuthAcquisition {
token_url: String,
reason: String,
},
OAuthAuthorizationUrl {
authorization_url: String,
reason: String,
},
}Expand description
Every way loading or sending a request can fail.
Typed rather than anyhow so front-ends can branch on the variant (e.g. a
TUI showing a “file missing” prompt vs. a network retry).
Variants§
Io
Parse
ParseStr(Error)
YAML that did not come from a file on disk (string input, tests).
Serialize(Error)
A document could not be serialized back to YAML —
Document::to_yaml_string.
In practice this should never happen for a Document built by
Document::from_path/from_yaml_str:
every field that came from real YAML serializes back out the same
way. But serde_yaml::to_string still returns a Result, and
.unwrap()-ing it would turn a theoretical serialization bug into a
panic on save instead of a message a front-end can show and recover
from.
SaveIo
A document could not be written back to disk after an edit —
Document::save_to_path. The save
half of Io, kept separate because the message has to say
“write” rather than “read”, and because a write failure here means the
edit was never persisted: the file at path is left exactly as it was
before the save was attempted (see save_to_path’s own doc comment
for why the write can never leave path half-written).
InvalidHeader
Network
Timeout
The request did not finish inside the configured timeout.
Split out of Network because it is the one network
failure whose cause is a Sendra setting. Every other one — DNS,
refused connection, TLS — is a statement about the network or the
server, and the fix is out there; this one says the server was still
working when Sendra stopped waiting, and the fix may well be a line in
.sendra/config.yaml. Folded into Network, all a user got was
“request to x failed / caused by: operation timed out”, which never
mentions that Sendra imposed the limit or what it was set to.
Carries the limit that was actually applied — the resolved
Config::timeout, not the raw
timeout_seconds key, which may not have been set at all — so the
message can name it whether it came from a config file or from
DEFAULT_TIMEOUT.
The whole-request timeout covers connect, send and body read, so this
is raised from either half of send_prepared: a
server that accepts the connection and then dribbles the body out too
slowly times out here exactly like one that never answers at all.
Fields
Client(Error)
The HTTP client itself could not be built, so nothing was sent and
nothing will be: this is a failure of the run’s configuration (a TLS
backend that will not initialise, say), not of one request. Separate
from Network because there is no URL to name — the
client is built once for the whole run, before any request is looked
at.
RequestNotFound
A named request was asked for, but the collection has no such name.
Carries the names that are available so a front-end can list them (or offer a “did you mean”) without re-reading the file.
NotACollection
A name was asked for, but the file holds a single request rather than a collection, so there is nothing to select from.
InvalidCollection
The file parsed as a collection but broke a rule serde cannot express:
requests must be non-empty, every request must have a name, and
those names must be unique.
InvalidRequest
A single request broke a rule serde cannot express: at most one of
body/json/body_file/form/multipart may be set, and each
multipart part needs exactly one of value/path. Raised at parse
time — for a collection, wrapped into InvalidCollection
with which request it was, the same way a duplicate name is.
BodyFileIo
A body_file (or a multipart path) named a file that could not be
read, or one whose content is not valid UTF-8. Distinct from
Io, which is about the request file itself not being
readable — this is about a file the request references, resolved
relative to the request file’s own directory. See
Request::resolve_body.
ClientCertIo
A client_cert/client_key path (from either config file, or
--client-cert/--client-key) named a file that could not be read.
Distinct from Client, which wraps only a
reqwest::Error: reading the file happens before reqwest is ever
involved, and the message needs to say which path was the problem.
ClientCertIncomplete
Only one of client_cert/client_key — from config, --client-cert/
--client-key, or a mix of both — resolved to a path. A client
certificate and its private key are only meaningful as a pair; sending
half of one silently would be worse than refusing to build the client
at all.
ConfigIo
A config file was found but could not be read. Separate from Io
so a front-end can say “your config is broken” rather than “your request
file is broken” — the user did not name this path on the command line
and needs to be told which file to go and fix.
ConfigParse
A config file was read but is not valid: bad YAML, an unknown key, or a value of the wrong type. Never silently ignored — a config that does not parse is a config whose settings are not being applied.
CurrentDir(Error)
The working directory could not be read, so the walk-up looking for a project config has nowhere to start.
EnvIo
An environment file was found but could not be read. Its own variant for
the same reason ConfigIo is: the user did not name
this path on the command line, so the error has to say which file to go
and fix.
EnvParse
An environment file was read but is not a flat map of string to string: bad YAML, a nested mapping, or a value that is not a string. Never ignored — an environment that does not parse is a set of variables that are not being substituted.
EnvSaveIo
An environment could not be written back to disk after an edit —
Environment::save_to_path. The
save half of EnvIo, kept separate for the same reason
SaveIo is split from Io: the message
has to say “write” rather than “read”, and a write failure here means
the edit was never persisted — the file at path is left exactly as
it was before the save was attempted.
InvalidEnvironment
An environment file parsed as valid YAML, but its auth: block broke
a rule serde cannot express: exactly one of bearer/basic/
api_key may be set — the same rule
Request::validate enforces for a
request’s own auth: block, reused here since an environment’s
auth: is the exact same Auth shape. Raised at
parse time, from Environment::from_yaml_str/
from_path — a collision between an
environment’s default auth: and a request’s own header/query is a
different failure, folded into InvalidRequest
instead, since it can only be discovered once a specific request is
being substituted against this environment.
VariableNotFound
A request referenced {{name}} and the active environment has no such
variable.
Carries the names that are defined, and the file they came from, the
way RequestNotFound carries the request names
a collection does have. Raised while the request is being built, so it
happens before anything goes over the wire.
Fields
environment: Option<PathBuf>The environment file the variable was looked for in, or None when
no environment file was found at all.
captured: Vec<String>The names captured by earlier requests in this run, which are looked up alongside the file’s own and so belong in the same message.
Listed separately from available rather than merged into it
because they did not come from the file the message names, and a
list that claimed they did would send the reader to edit a file that
has never mentioned them. Empty for a single request, and for every
run of a collection that captures nothing — in which case the
message is exactly the one it has always been.
EnvVarNotSet
An environment file value is ${VAR} and VAR is not in the OS
environment.
Deliberately an error rather than an empty string: silently sending
Authorization: Bearer would turn a missing secret into a puzzling 401
instead of a message naming the variable to export.
Fields
ScriptParse
A pre_request or post_request script does not parse.
Its own variant, separate from ScriptFailed,
because they are different problems for a user to fix — the same reason
config and environment each split IO from Parse. A script that does not
compile is a broken file: nothing about the request or the response
could have changed the outcome, and the fix is a syntax error at a
position Rhai names. Both hooks are compiled before the request is sent,
so this is always raised with nothing having gone over the wire.
ScriptFailed
A script compiled, ran, and threw — or hit a runtime error.
Only ever produced for pre_request. A post_request script that fails
is a statement about a response that did arrive, so it comes back as
ScriptOutcome::Failed rather than as
an error; see the note on that type.
ScriptRequest
A pre_request script ran without throwing but left request in a
state that is not a request: an unknown field, a value of the wrong
type, or an assignment to the read-only method.
Separate from ScriptFailed because the script
did not fail — it succeeded at doing something Sendra cannot act on, and
the fix is a line of the script rather than whatever it was checking.
OAuthAcquisition
An auth.oauth token acquisition failed: bad credentials, an
unreachable or non-2xx token endpoint, or a response with no
access_token.
Raised lazily, only when a request whose auth.oauth needs a token is
about to run — Request::resolve_oauth,
called just before Request::resolve_auth
— rather than up front for the whole run, since it happens per-request
the same way a substitution failure does. A request whose acquisition
fails is a per-request failure with no response, the same category
VariableNotFound already is; the siblings around it, using other
auth or none at all, are unaffected. See crate::oauth for the
in-run cache this reads and writes, and for why a failure for a given
oauth: config is remembered rather than retried for every later
request that shares it.
OAuthAuthorizationUrl
Could not build an authorization_code login’s authorization URL:
auth.oauth.authorization_url did not parse as a URL. Raised by
crate::oauth::build_authorization_url, the one step of the
interactive login flow that runs before any browser or network call —
see crate::oauth’s module docs.
Trait Implementations§
Source§impl Debug for SendraError
impl Debug for SendraError
Source§impl Display for SendraError
impl Display for SendraError
Source§impl Error for SendraError
impl Error for SendraError
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()