use crate::iam::Error as IamError;
use crate::idx::ft::MatchRef;
use crate::idx::trees::vector::SharedVector;
use crate::sql::idiom::Idiom;
use crate::sql::index::Distance;
use crate::sql::thing::Thing;
use crate::sql::value::Value;
use crate::syn::error::RenderedError as RenderedParserError;
use crate::vs::VersionStampError;
use base64::DecodeError as Base64Error;
use bincode::Error as BincodeError;
#[cfg(storage)]
use ext_sort::SortError;
use fst::Error as FstError;
use jsonwebtoken::errors::Error as JWTError;
use object_store::Error as ObjectStoreError;
use revision::Error as RevisionError;
use serde::Serialize;
use std::io::Error as IoError;
use std::string::FromUtf8Error;
use storekey::decode::Error as DecodeError;
use storekey::encode::Error as EncodeError;
use thiserror::Error;
#[derive(Error, Debug)]
#[non_exhaustive]
pub enum Error {
#[doc(hidden)]
#[error("Conditional clause is not truthy")]
Ignore,
#[doc(hidden)]
#[error("Break statement has been reached")]
Break,
#[doc(hidden)]
#[error("Continue statement has been reached")]
Continue,
#[doc(hidden)]
#[error("This document should be retried with a new ID")]
RetryWithId(Thing),
#[error("The database encountered unreachable logic: {0}")]
Unreachable(String),
#[error("{0}")]
Deprecated(String),
#[error("An error occurred: {0}")]
Thrown(String),
#[error("There was a problem with the underlying datastore: {0}")]
Ds(String),
#[error("There was a problem with a datastore transaction: {0}")]
Tx(String),
#[error("There was an error when starting a new datastore transaction")]
TxFailure,
#[error("Couldn't update a finished transaction")]
TxFinished,
#[error("Couldn't write to a read only transaction")]
TxReadonly,
#[error("Value being checked was not correct")]
TxConditionNotMet,
#[error("The key being inserted already exists")]
TxKeyAlreadyExists,
#[error("Record id or key is too large")]
TxKeyTooLarge,
#[error("Record or value is too large")]
TxValueTooLarge,
#[error("Failed to commit transaction due to a read or write conflict. This transaction can be retried")]
TxRetryable,
#[error("Transaction is too large")]
TxTooLarge,
#[error("Specify a namespace to use")]
NsEmpty,
#[error("Specify a database to use")]
DbEmpty,
#[error("Specify some SQL code to execute")]
QueryEmpty,
#[error("The SQL query was not parsed fully")]
QueryRemaining,
#[error("Parse error: {0}")]
InvalidQuery(RenderedParserError),
#[error("Can not use {value} in a CONTENT clause")]
InvalidContent {
value: Value,
},
#[error("Can not use {value} in a MERGE clause")]
InvalidMerge {
value: Value,
},
#[error("The JSON Patch contains invalid operations. {message}")]
InvalidPatch {
message: String,
},
#[error("Given test operation failed for JSON Patch. Expected `{expected}`, but got `{got}` instead.")]
PatchTest {
expected: String,
got: String,
},
#[error("Remote HTTP request functions are not enabled")]
HttpDisabled,
#[error("'{name}' is a protected variable and cannot be set")]
InvalidParam {
name: String,
},
#[error("Found '{field}' in SELECT clause on line {line}, but field is not an aggregate function, and is not present in GROUP BY expression")]
InvalidField {
line: usize,
field: String,
},
#[error("Found {value} on FETCH CLAUSE, but FETCH expects an idiom, a string or fields")]
InvalidFetch {
value: Value,
},
#[error("Found '{field}' in SPLIT ON clause on line {line}, but field is not present in SELECT expression")]
InvalidSplit {
line: usize,
field: String,
},
#[error("Found '{field}' in ORDER BY clause on line {line}, but field is not present in SELECT expression")]
InvalidOrder {
line: usize,
field: String,
},
#[error("Found '{field}' in GROUP BY clause on line {line}, but field is not present in SELECT expression")]
InvalidGroup {
line: usize,
field: String,
},
#[error("Found {value} but the LIMIT clause must evaluate to a positive integer")]
InvalidLimit {
value: String,
},
#[error("Found {value} but the START clause must evaluate to a positive integer")]
InvalidStart {
value: String,
},
#[error("Problem with embedded script function. {message}")]
InvalidScript {
message: String,
},
#[error("Problem with machine learning computation. {message}")]
InvalidModel {
message: String,
},
#[error("There was a problem running the {name}() function. {message}")]
InvalidFunction {
name: String,
message: String,
},
#[error("Incorrect arguments for function {name}(). {message}")]
InvalidArguments {
name: String,
message: String,
},
#[error("Incorrect arguments for aggregate function {name}() on table '{table}'. {message}")]
InvalidAggregation {
name: String,
table: String,
message: String,
},
#[error("There was a problem running the {name} function. Expected this function to return a value of type {check}, but found {value}")]
FunctionCheck {
name: String,
value: String,
check: String,
},
#[error("The URL `{0}` is invalid")]
InvalidUrl(String),
#[error("Incorrect vector dimension ({current}). Expected a vector of {expected} dimension.")]
InvalidVectorDimension {
current: usize,
expected: usize,
},
#[error("Unable to compute distance.The calculated result is not a valid number: {dist}. Vectors: {left:?} - {right:?}")]
InvalidVectorDistance {
left: SharedVector,
right: SharedVector,
dist: f64,
},
#[error("The vector element ({current}) is not a number.")]
InvalidVectorType {
current: String,
expected: &'static str,
},
#[error("The value cannot be converted to a vector: {0}")]
InvalidVectorValue(String),
#[error("Invalid regular expression: {0:?}")]
InvalidRegex(String),
#[error("Invalid timeout: {0:?} seconds")]
InvalidTimeout(u64),
#[error("The query was not executed because it exceeded the timeout")]
QueryTimedout,
#[error("The query was not executed due to a cancelled transaction")]
QueryCancelled,
#[error("The query was not executed due to a failed transaction")]
QueryNotExecuted,
#[error("The query was not executed due to a failed transaction. {message}")]
QueryNotExecutedDetail {
message: String,
},
#[error("You don't have permission to change to the {ns} namespace")]
NsNotAllowed {
ns: String,
},
#[error("You don't have permission to change to the {db} database")]
DbNotAllowed {
db: String,
},
#[error("The namespace '{value}' does not exist")]
NsNotFound {
value: String,
},
#[error("The namespace login '{value}' does not exist")]
NlNotFound {
value: String,
},
#[error("The database '{value}' does not exist")]
DbNotFound {
value: String,
},
#[error("The database login '{value}' does not exist")]
DlNotFound {
value: String,
},
#[error("The event '{value}' does not exist")]
EvNotFound {
value: String,
},
#[error("The function 'fn::{value}' does not exist")]
FcNotFound {
value: String,
},
#[error("The field '{value}' does not exist")]
FdNotFound {
value: String,
},
#[error("The model 'ml::{value}' does not exist")]
MlNotFound {
value: String,
},
#[error("The node '{value}' does not exist")]
NdNotFound {
value: String,
},
#[error("The param '${value}' does not exist")]
PaNotFound {
value: String,
},
#[error("The config for {value} does not exist")]
CgNotFound {
value: String,
},
#[error("The table '{value}' does not exist")]
TbNotFound {
value: String,
},
#[error("The live query '{value}' does not exist")]
LvNotFound {
value: String,
},
#[error("The cluster live query '{value}' does not exist")]
LqNotFound {
value: String,
},
#[error("The analyzer '{value}' does not exist")]
AzNotFound {
value: String,
},
#[error("The index '{value}' does not exist")]
IxNotFound {
value: String,
},
#[error("The record '{value}' does not exist")]
IdNotFound {
value: String,
},
#[error("Unsupported distance: {0}")]
UnsupportedDistance(Distance),
#[error("The root user '{value}' does not exist")]
UserRootNotFound {
value: String,
},
#[error("The user '{value}' does not exist in the namespace '{ns}'")]
UserNsNotFound {
value: String,
ns: String,
},
#[error("The user '{value}' does not exist in the database '{db}'")]
UserDbNotFound {
value: String,
ns: String,
db: String,
},
#[error("Unable to perform the realtime query")]
RealtimeDisabled,
#[error("Reached excessive computation depth due to functions, subqueries, or futures")]
ComputationDepthExceeded,
#[error("Can not execute statement using value '{value}'")]
InvalidStatementTarget {
value: String,
},
#[error("Can not execute CREATE statement using value '{value}'")]
CreateStatement {
value: String,
},
#[error("Can not execute UPSERT statement using value '{value}'")]
UpsertStatement {
value: String,
},
#[error("Can not execute UPDATE statement using value '{value}'")]
UpdateStatement {
value: String,
},
#[error("Can not execute RELATE statement using value '{value}'")]
RelateStatement {
value: String,
},
#[error("Can not execute RELATE statement where property 'in' is '{value}'")]
RelateStatementIn {
value: String,
},
#[error("Can not execute RELATE statement where property 'id' is '{value}'")]
RelateStatementId {
value: String,
},
#[error("Can not execute RELATE statement where property 'out' is '{value}'")]
RelateStatementOut {
value: String,
},
#[error("Can not execute DELETE statement using value '{value}'")]
DeleteStatement {
value: String,
},
#[error("Can not execute INSERT statement using value '{value}'")]
InsertStatement {
value: String,
},
#[error("Can not execute INSERT statement where property 'in' is '{value}'")]
InsertStatementIn {
value: String,
},
#[error("Can not execute INSERT statement where property 'id' is '{value}'")]
InsertStatementId {
value: String,
},
#[error("Can not execute INSERT statement where property 'out' is '{value}'")]
InsertStatementOut {
value: String,
},
#[error("Can not execute LIVE statement using value '{value}'")]
LiveStatement {
value: String,
},
#[error("Can not execute KILL statement using id '{value}'")]
KillStatement {
value: String,
},
#[error("Expected a single result output when using the ONLY keyword")]
SingleOnlyOutput,
#[error("You don't have permission to run this query on the `{table}` table")]
TablePermissions {
table: String,
},
#[error("You don't have permission to view the ${name} parameter")]
ParamPermissions {
name: String,
},
#[error("You don't have permission to run the fn::{name} function")]
FunctionPermissions {
name: String,
},
#[error("Unable to write to the `{table}` table while setup as a view")]
TableIsView {
table: String,
},
#[error("Database record `{thing}` already exists")]
RecordExists {
thing: Thing,
},
#[error("Database index `{index}` already contains {value}, with record `{thing}`")]
IndexExists {
thing: Thing,
index: String,
value: String,
},
#[error("Found record: `{thing}` which is {}a relation, but expected a {target_type}", if *relation { "not " } else { "" })]
TableCheck {
thing: String,
relation: bool,
target_type: String,
},
#[error("Found {value} for field `{field}`, with record `{thing}`, but expected a {check}")]
FieldCheck {
thing: String,
value: String,
field: Idiom,
check: String,
},
#[error("Found {value} for field `{field}`, with record `{thing}`, but field must conform to: {check}")]
FieldValue {
thing: String,
value: String,
field: Idiom,
check: String,
},
#[error("Found {value} for param ${name}, but expected a {check}")]
SetCheck {
value: String,
name: String,
check: String,
},
#[error(
"Found changed value for field `{field}`, with record `{thing}`, but field is readonly"
)]
FieldReadonly {
thing: String,
field: Idiom,
},
#[error("Found field '{field}', but no such field exists for table '{table}'")]
FieldUndefined {
table: String,
field: Idiom,
},
#[error("Found {value} for the Record ID but this is not a valid id")]
IdInvalid {
value: String,
},
#[error("Found {value} for the `id` field, but a specific record has been specified")]
IdMismatch {
value: String,
},
#[error("Found {value} for the incoming relation, but this is not a valid Record ID")]
InInvalid {
value: String,
},
#[error("Found {value} for the `in` field, but the value does not match the `in` record id")]
InMismatch {
value: String,
},
#[error("Found {value} for the `in` field, which does not match the existing field value")]
InOverride {
value: String,
},
#[error("Found {value} for the outgoing relation, but this is not a valid Record ID")]
OutInvalid {
value: String,
},
#[error("Found {value} for the `out` field, but the value does not match the `out` record id")]
OutMismatch {
value: String,
},
#[error("Found {value} for the `out` field, which does not match the existing field value")]
OutOverride {
value: String,
},
#[error("Expected a {into} but found {from}")]
CoerceTo {
from: Value,
into: String,
},
#[error("Expected a {into} but cannot convert {from} into a {into}")]
ConvertTo {
from: Value,
into: String,
},
#[error("Expected a {kind} but the array had {size} items")]
LengthInvalid {
kind: String,
size: usize,
},
#[error("Cannot perform addition with '{0}' and '{1}'")]
TryAdd(String, String),
#[error("Cannot perform subtraction with '{0}' and '{1}'")]
TrySub(String, String),
#[error("Cannot perform multiplication with '{0}' and '{1}'")]
TryMul(String, String),
#[error("Cannot perform division with '{0}' and '{1}'")]
TryDiv(String, String),
#[error("Cannot perform remainder with '{0}' and '{1}'")]
TryRem(String, String),
#[error("Cannot raise the value '{0}' with '{1}'")]
TryPow(String, String),
#[error("Cannot negate the value '{0}'")]
TryNeg(String),
#[error("Cannot convert from '{0}' to '{1}'")]
TryFrom(String, &'static str),
#[error("There was an error processing a remote HTTP request: {0}")]
Http(String),
#[error("There was an error processing a value in parallel: {0}")]
Channel(String),
#[error("I/O error: {0}")]
Io(#[from] IoError),
#[error("Key encoding error: {0}")]
Encode(#[from] EncodeError),
#[error("Key decoding error: {0}")]
Decode(#[from] DecodeError),
#[error("Versioned error: {0}")]
Revision(#[from] RevisionError),
#[error("Index is corrupted: {0}")]
CorruptedIndex(&'static str),
#[error("There was no suitable index supporting the expression '{value}'")]
NoIndexFoundForMatch {
value: String,
},
#[error("A value can't be analyzed: {0}")]
AnalyzerError(String),
#[error("A value can't be highlighted: {0}")]
HighlightError(String),
#[error("Bincode error: {0}")]
Bincode(#[from] BincodeError),
#[error("FstError error: {0}")]
FstError(#[from] FstError),
#[error("Utf8 error: {0}")]
Utf8Error(#[from] FromUtf8Error),
#[error("Object Store error: {0}")]
ObsError(#[from] ObjectStoreError),
#[error("There was an error with model computation: {0}")]
ModelComputation(String),
#[error("Feature not yet implemented: {feature}")]
FeatureNotYetImplemented {
feature: String,
},
#[error("Duplicated Match reference: {mr}")]
DuplicatedMatchRef {
mr: MatchRef,
},
#[error("Timestamp arithmetic error: {0}")]
TimestampOverflow(String),
#[error("Internal database error: {0}")]
Internal(String),
#[error("Unimplemented functionality: {0}")]
Unimplemented(String),
#[error("Versionstamp in key is corrupted: {0}")]
CorruptedVersionstampInKey(#[from] VersionStampError),
#[error("Invalid level '{0}'")]
InvalidLevel(String),
#[error("IAM error: {0}")]
IamError(#[from] IamError),
#[error("Scripting functions are not allowed")]
ScriptingNotAllowed,
#[error("Function '{0}' is not allowed to be executed")]
FunctionNotAllowed(String),
#[error("Access to network target '{0}' is not allowed")]
NetTargetNotAllowed(String),
#[error("There was an error creating the token")]
TokenMakingFailed,
#[error("No record was returned")]
NoRecordFound,
#[error("The signup query failed")]
SignupQueryFailed,
#[error("The signin query failed")]
SigninQueryFailed,
#[error("Username or Password was not provided")]
MissingUserOrPass,
#[error("No signin target to either SC or DB or NS or KV")]
NoSigninTarget,
#[error("The password did not verify")]
InvalidPass,
#[error("There was a problem with authentication")]
InvalidAuth,
#[error("There was an unexpected error while performing authentication")]
UnexpectedAuth,
#[error("There was a problem with signing up")]
InvalidSignup,
#[error("Auth was expected to be set but was unknown")]
UnknownAuth,
#[error("Auth token is missing the '{0}' header")]
MissingTokenHeader(String),
#[error("Auth token is missing the '{0}' claim")]
MissingTokenClaim(String),
#[error("The db is running without an available storage engine")]
MissingStorageEngine,
#[error("The node '{value}' already exists")]
ClAlreadyExists {
value: String,
},
#[error("The analyzer '{value}' already exists")]
AzAlreadyExists {
value: String,
},
#[error("The database '{value}' already exists")]
DbAlreadyExists {
value: String,
},
#[error("The event '{value}' already exists")]
EvAlreadyExists {
value: String,
},
#[error("The field '{value}' already exists")]
FdAlreadyExists {
value: String,
},
#[error("The function 'fn::{value}' already exists")]
FcAlreadyExists {
value: String,
},
#[error("The index '{value}' already exists")]
IxAlreadyExists {
value: String,
},
#[error("The model '{value}' already exists")]
MlAlreadyExists {
value: String,
},
#[error("The namespace '{value}' already exists")]
NsAlreadyExists {
value: String,
},
#[error("The param '${value}' already exists")]
PaAlreadyExists {
value: String,
},
#[error("The config for {value} already exists")]
CgAlreadyExists {
value: String,
},
#[error("The table '{value}' already exists")]
TbAlreadyExists {
value: String,
},
#[error("The namespace token '{value}' already exists")]
NtAlreadyExists {
value: String,
},
#[error("The database token '{value}' already exists")]
DtAlreadyExists {
value: String,
},
#[error("The root user '{value}' already exists")]
UserRootAlreadyExists {
value: String,
},
#[error("The user '{value}' already exists in the namespace '{ns}'")]
UserNsAlreadyExists {
value: String,
ns: String,
},
#[error("The user '{value}' already exists in the database '{db}'")]
UserDbAlreadyExists {
value: String,
ns: String,
db: String,
},
#[error("Database index `{index}` is currently building")]
IndexAlreadyBuilding {
index: String,
},
#[error("The token has expired")]
ExpiredToken,
#[error("The session has expired")]
ExpiredSession,
#[error("A node task has failed: {0}")]
NodeAgent(&'static str),
#[error("Serialization error: {0}")]
Serialization(String),
#[error("The root access method '{ac}' already exists")]
AccessRootAlreadyExists {
ac: String,
},
#[error("The access method '{ac}' already exists in the namespace '{ns}'")]
AccessNsAlreadyExists {
ac: String,
ns: String,
},
#[error("The access method '{ac}' already exists in the database '{db}'")]
AccessDbAlreadyExists {
ac: String,
ns: String,
db: String,
},
#[error("The root access method '{ac}' does not exist")]
AccessRootNotFound {
ac: String,
},
#[error("The root access grant '{gr}' does not exist for '{ac}'")]
AccessGrantRootNotFound {
ac: String,
gr: String,
},
#[error("The access method '{ac}' does not exist in the namespace '{ns}'")]
AccessNsNotFound {
ac: String,
ns: String,
},
#[error("The access grant '{gr}' does not exist for '{ac}' in the namespace '{ns}'")]
AccessGrantNsNotFound {
ac: String,
gr: String,
ns: String,
},
#[error("The access method '{ac}' does not exist in the database '{db}'")]
AccessDbNotFound {
ac: String,
ns: String,
db: String,
},
#[error("The access grant '{gr}' does not exist for '{ac}' in the database '{db}'")]
AccessGrantDbNotFound {
ac: String,
gr: String,
ns: String,
db: String,
},
#[error("The access method cannot be defined on the requested level")]
AccessLevelMismatch,
#[error("The access method cannot be used in the requested operation")]
AccessMethodMismatch,
#[error("The access method does not exist")]
AccessNotFound,
#[error("This access method has an invalid duration")]
AccessInvalidDuration,
#[error("This access method results in an invalid expiration")]
AccessInvalidExpiration,
#[error("The record access signup query failed")]
AccessRecordSignupQueryFailed,
#[error("The record access signin query failed")]
AccessRecordSigninQueryFailed,
#[error("This record access method does not allow signup")]
AccessRecordNoSignup,
#[error("This record access method does not allow signin")]
AccessRecordNoSignin,
#[error("This bearer access method requires a key to be provided")]
AccessBearerMissingKey,
#[error("This bearer access grant has an invalid format")]
AccessGrantBearerInvalid,
#[error("This access grant has an invalid subject")]
AccessGrantInvalidSubject,
#[error("This access grant has been revoked")]
AccessGrantRevoked,
#[error("Found {value} for the Record ID but this is not a valid table name")]
TbInvalid {
value: String,
},
#[doc(hidden)]
#[error("Return statement has been reached")]
Return {
value: Value,
},
#[error("{variant} destructuring method is not supported here")]
UnsupportedDestructure {
variant: String,
},
#[doc(hidden)]
#[error("The underlying datastore does not support versioned queries")]
UnsupportedVersionedQueries,
#[error("Expected a range value of '{expected}', but found '{found}'")]
InvalidRangeValue {
expected: String,
found: String,
},
#[error("The range cannot exceed a size of {max} for this operation")]
RangeTooBig {
max: usize,
},
#[error("There was an invalid storage version stored in the database")]
InvalidStorageVersion,
#[error("The data stored on disk is out-of-date with this version. Please follow the upgrade guides in the documentation")]
OutdatedStorageVersion,
#[error("Found a non-computed value where they are not allowed")]
NonComputed,
#[error("Size of query script exceeded maximum supported size of 4,294,967,295 bytes.")]
QueryTooLarge,
#[error("Failed to compute: \"{0}\", as the operation results in an arithmetic overflow.")]
ArithmeticOverflow(String),
#[error("Failed to compute: \"{0}\", as the operation results in a negative value.")]
ArithmeticNegativeOverflow(String),
#[error("Failed to allocate space for \"{0}\"")]
InsufficientReserve(String),
#[error("Received error while streaming query: {0}.")]
QueryStream(String),
#[error("Error while ordering a result: {0}.")]
OrderingError(String),
#[error("Encountered an issue while processed export config: found {0}, but expected {1}.")]
InvalidExportConfig(Value, String),
#[error("Found {found} for bound but expected {expected}.")]
InvalidBound {
found: String,
expected: String,
},
#[error("Exceeded the idiom recursion limit of {limit}.")]
IdiomRecursionLimitExceeded {
limit: u32,
},
#[error("Tried to use a `@` repeat recurse symbol, while not recursing.")]
RepeatRecurseNotRecursing,
#[error("Tried to use a `{symbol}` recursion symbol, while already recursing.")]
IdiomRecursionAlreadyRecursing {
symbol: String,
},
#[error("Tried to use a `@` repeat recurse symbol in a position where it is not supported")]
UnsupportedRepeatRecurse,
#[error("Error while computing version: expected a datetime, but found {found}")]
InvalidVersion {
found: Value,
},
#[error("Can not construct a recursion plan when an instruction is provided")]
RecursionInstructionPlanConflict,
#[error("Cannot delete `{0}` as it is referenced by `{1}` with an ON DELETE REJECT clause")]
DeleteRejectedByReference(String, String),
#[error(
"Cannot use the `REFERENCE` keyword with `TYPE {0}`. Specify a `record` type, or a type containing only records, instead."
)]
ReferenceTypeConflict(String),
#[error("Cannot use the `{0}` keyword with `TYPE {0}`.")]
RefsTypeConflict(String, String),
#[error("When specifying a `TYPE` clause with `references`, all variants must be of type `references`.")]
RefsMismatchingVariants,
#[error("An error occured while updating references for `{0}`: {1}")]
RefsUpdateFailure(String, String),
#[error("Cannot obtain a list of references as there is no Record ID in the context for the operation")]
InvalidRefsContext,
#[error("Cannot set field `{name}` with type `{kind}` as it mismatched with field `{existing_name}` with type `{existing_kind}`")]
MismatchedFieldTypes {
name: String,
kind: String,
existing_name: String,
existing_kind: String,
},
}
impl From<Error> for String {
fn from(e: Error) -> String {
e.to_string()
}
}
impl From<Base64Error> for Error {
fn from(_: Base64Error) -> Error {
Error::InvalidAuth
}
}
impl From<JWTError> for Error {
fn from(_: JWTError) -> Error {
Error::InvalidAuth
}
}
impl From<regex::Error> for Error {
fn from(error: regex::Error) -> Self {
Error::InvalidRegex(error.to_string())
}
}
#[cfg(any(feature = "kv-mem", feature = "kv-surrealkv"))]
impl From<surrealkv::Error> for Error {
fn from(e: surrealkv::Error) -> Error {
match e {
surrealkv::Error::TransactionReadConflict => Error::TxRetryable,
surrealkv::Error::TransactionWriteConflict => Error::TxRetryable,
_ => Error::Tx(e.to_string()),
}
}
}
#[cfg(feature = "kv-rocksdb")]
impl From<rocksdb::Error> for Error {
fn from(e: rocksdb::Error) -> Error {
match e.kind() {
rocksdb::ErrorKind::Busy => Error::TxRetryable,
rocksdb::ErrorKind::TryAgain => Error::TxRetryable,
_ => Error::Tx(e.to_string()),
}
}
}
#[cfg(feature = "kv-indxdb")]
impl From<indxdb::err::Error> for Error {
fn from(e: indxdb::err::Error) -> Error {
match e {
indxdb::err::Error::KeyAlreadyExists => Error::TxKeyAlreadyExists,
indxdb::err::Error::ValNotExpectedValue => Error::TxConditionNotMet,
_ => Error::Tx(e.to_string()),
}
}
}
#[cfg(feature = "kv-tikv")]
impl From<tikv::Error> for Error {
fn from(e: tikv::Error) -> Error {
match e {
tikv::Error::DuplicateKeyInsertion => Error::TxKeyAlreadyExists,
tikv::Error::KeyError(ke) if ke.conflict.is_some() => Error::TxRetryable,
tikv::Error::KeyError(ke) if ke.abort.contains("KeyTooLarge") => Error::TxKeyTooLarge,
tikv::Error::RegionError(re) if re.raft_entry_too_large.is_some() => Error::TxTooLarge,
_ => Error::Tx(e.to_string()),
}
}
}
#[cfg(feature = "kv-fdb")]
impl From<foundationdb::FdbError> for Error {
fn from(e: foundationdb::FdbError) -> Error {
if e.is_retryable() {
return Error::TxRetryable;
}
if e.is_retryable_not_committed() {
return Error::TxRetryable;
}
Error::Ds(e.to_string())
}
}
#[cfg(feature = "kv-fdb")]
impl From<foundationdb::TransactionCommitError> for Error {
fn from(e: foundationdb::TransactionCommitError) -> Error {
if e.is_retryable() {
return Error::TxRetryable;
}
if e.is_retryable_not_committed() {
return Error::TxRetryable;
}
Error::Tx(e.to_string())
}
}
impl From<async_channel::RecvError> for Error {
fn from(e: async_channel::RecvError) -> Error {
Error::Channel(e.to_string())
}
}
impl<T> From<async_channel::SendError<T>> for Error {
fn from(e: async_channel::SendError<T>) -> Error {
Error::Channel(e.to_string())
}
}
#[cfg(any(feature = "http", feature = "jwks"))]
impl From<reqwest::Error> for Error {
fn from(e: reqwest::Error) -> Error {
Error::Http(e.to_string())
}
}
#[cfg(storage)]
impl<S, D, I> From<SortError<S, D, I>> for Error
where
S: std::error::Error,
D: std::error::Error,
I: std::error::Error,
{
fn from(e: SortError<S, D, I>) -> Error {
Error::Internal(e.to_string())
}
}
impl Serialize for Error {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(self.to_string().as_str())
}
}
impl Error {
pub fn is_schema_related(&self) -> bool {
matches!(
self,
Error::FieldCheck { .. }
| Error::FieldValue { .. }
| Error::FieldReadonly { .. }
| Error::FieldUndefined { .. }
)
}
pub fn set_check_from_coerce(self, name: String) -> Error {
match self {
Error::CoerceTo {
from,
into,
} => Error::SetCheck {
name,
value: from.to_string(),
check: into,
},
e => e,
}
}
pub fn function_check_from_coerce(self, name: impl Into<String>) -> Error {
match self {
Error::CoerceTo {
from,
into,
} => Error::FunctionCheck {
name: name.into(),
value: from.to_string(),
check: into,
},
e => e,
}
}
}