pub enum SearchError {
Show 13 variants
IndexNotFound {
index: String,
},
IndexAlreadyExists {
index: String,
},
MapperParsing {
kind: String,
reason: String,
},
VersionConflict {
index: String,
id: String,
reason: String,
},
Overloaded {
kind: String,
reason: String,
},
Unauthorized {
reason: String,
},
Forbidden {
reason: String,
},
BadRequest {
kind: String,
reason: String,
},
Unavailable {
status: u16,
reason: String,
},
BulkPartialFailure {
failed: usize,
total: usize,
first: String,
},
Unexpected {
status: u16,
kind: String,
reason: String,
},
Transport(String),
Malformed {
context: String,
message: String,
},
}Expand description
A failure from Elasticsearch or OpenSearch.
Variants§
IndexNotFound
The index does not exist.
Usually a typo or a missing bootstrap step rather than an outage, and worth telling apart from an empty result: searching a misspelled index and searching an index with nothing in it look identical from the caller’s side otherwise.
IndexAlreadyExists
The index already exists, from a create that assumed it did not.
Ordinary in a startup path that creates its indices every boot, which
is why crate::SearchClient::create_index_if_missing exists.
MapperParsing
The document does not fit the mapping.
A string where the mapping says long, a field the index refuses under
dynamic: strict, an unparseable date. Never retryable — the same
bytes will be rejected the same way for as long as the mapping stands.
The reason carries the underlying cause where the cluster gives one,
because failed to parse field [price] without it names the field but
not the problem.
VersionConflict
The document changed since it was read.
Optimistic concurrency working as intended: something else wrote this
document first. Retrying the identical request cannot help, but reading
the document again and reapplying the change usually can — which is why
this is not folded into SearchError::is_retryable.
Overloaded
The cluster refused the work to stay alive.
A circuit breaker tripping, a full search or write queue, an index blocked by a disk watermark. The request was not performed, so backing off and repeating it is safe and is usually the correct response.
401 — no credentials, or credentials the cluster does not accept.
Fields
Forbidden
403 — authenticated, but not allowed to do this.
Separate from SearchError::Unauthorized because the fixes have
nothing in common: one is a wrong password, the other a missing role.
BadRequest
A request the cluster could parse but not accept — a malformed query, an illegal argument, an unknown parameter.
The cluster is not answering: a gateway in front of it, a node restarting, a shard with no copy available.
BulkPartialFailure
Some documents in a _bulk request were not written.
The one failure the HTTP status will never tell you about: _bulk
answers 200 whether every item succeeded or none did, and reports the
per-item outcome in the body. This exists so that
crate::BulkReport::ok_or_error can turn that into an error a ?
notices, for the callers that would rather not inspect every item.
Which items, and why, is in the report — the reasons differ per item,
so retryability cannot be decided for the request as a whole.
Unexpected
Anything else the cluster answered.
Transport(String)
The request never reached the cluster.
Malformed
The cluster answered successfully with a shape this crate cannot read.
Distinct from every variant above, which are the cluster saying no. This one is a yes in a form we did not expect — a proxy rewriting the body, or a version whose response layout moved — and naming what was being parsed is the only thing that makes it diagnosable.
Implementations§
Source§impl SearchError
impl SearchError
Sourcepub fn from_response(status: u16, context: &str, body: &str) -> SearchError
pub fn from_response(status: u16, context: &str, body: &str) -> SearchError
Build from a status code and whatever body came with it.
context names what was being attempted; it is used only where the
body does not identify the resource itself, which is common for a
document-level failure.
Sourcepub fn is_retryable(&self) -> bool
pub fn is_retryable(&self) -> bool
Whether repeating the identical request could plausibly succeed.
The judgement callers most need and most often get wrong. A rejected write never happened, so repeating it after a pause is both safe and likely to work. A mapping error, a bad query and a permission failure will fail the same way for as long as nothing else changes, and retrying them only turns one clear log line into a hundred.
A version conflict is deliberately not retryable even though a later attempt may well succeed: the request that lost carries a stale document, and sending it again would overwrite the winner.
Sourcepub fn is_conflict(&self) -> bool
pub fn is_conflict(&self) -> bool
Whether re-reading the document and reapplying the change could work.
pub fn is_index_not_found(&self) -> bool
Sourcepub fn is_auth_failure(&self) -> bool
pub fn is_auth_failure(&self) -> bool
Whether the failure is about credentials rather than the request.
Trait Implementations§
Source§impl Clone for SearchError
impl Clone for SearchError
Source§impl Debug for SearchError
impl Debug for SearchError
Source§impl Display for SearchError
impl Display for SearchError
impl Eq for SearchError
Source§impl Error for SearchError
impl Error for SearchError
1.30.0 · 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()