use crate::api::Response;
use crate::sql::Array;
use crate::sql::Edges;
use crate::sql::FromValueError;
use crate::sql::Object;
use crate::sql::Thing;
use crate::sql::Value;
use serde::Serialize;
use std::io;
use std::path::PathBuf;
use thiserror::Error;
#[derive(Error, Debug)]
#[non_exhaustive]
pub enum Error {
#[error("{0}")]
Query(String),
#[error("There was an error processing a remote HTTP request: {0}")]
Http(String),
#[error("There was an error processing a remote WS request: {0}")]
Ws(String),
#[error("Unsupported protocol or storage engine, `{0}`")]
Scheme(String),
#[error("Connection uninitialised")]
ConnectionUninitialised,
#[error("Already connected")]
AlreadyConnected,
#[error("Invalid bindings: {0}")]
InvalidBindings(Value),
#[error("Range on record IDs not supported: {0}")]
RangeOnRecordId(Thing),
#[error("Range on objects not supported: {0}")]
RangeOnObject(Object),
#[error("Range on arrays not supported: {0}")]
RangeOnArray(Array),
#[error("Range on edges not supported: {0}")]
RangeOnEdges(Edges),
#[error("`{table}:{id}` is not allowed as a method parameter; try `({table}, {id})`")]
TableColonId {
table: String,
id: String,
},
#[error("Duplicate request ID: {0}")]
DuplicateRequestId(i64),
#[error("Invalid request: {0}")]
InvalidRequest(String),
#[error("Invalid params: {0}")]
InvalidParams(String),
#[error("Internal error: {0}")]
InternalError(String),
#[error("Parse error: {0}")]
ParseError(String),
#[error("Invalid semantic version: {0}")]
InvalidSemanticVersion(String),
#[error("Invalid URL: {0}")]
InvalidUrl(String),
#[error("Failed to convert `{value}` to `T`: {error}")]
FromValue {
value: Value,
error: String,
},
#[error("Failed to deserialize a binary response: {error}")]
ResponseFromBinary {
binary: Vec<u8>,
error: bincode::Error,
},
#[error("Failed to serialize `{value}` to JSON string: {error}")]
ToJsonString {
value: Value,
error: String,
},
#[error("Failed to deserialize `{string}` to sql::Value: {error}")]
FromJsonString {
string: String,
error: String,
},
#[error("Invalid namespace name: {0:?}")]
InvalidNsName(String),
#[error("Invalid database name: {0:?}")]
InvalidDbName(String),
#[error("Failed to open `{path}`: {error}")]
FileOpen {
path: PathBuf,
error: io::Error,
},
#[error("Failed to read `{path}`: {error}")]
FileRead {
path: PathBuf,
error: io::Error,
},
#[error("Tried to take only a single result from a query that contains multiple")]
LossyTake(Response),
#[error("The protocol or storage engine does not support backups on this architecture")]
BackupsNotSupported,
#[error("server version `{server_version}` does not match the range supported by the client `{supported_versions}`")]
VersionMismatch {
server_version: semver::Version,
supported_versions: String,
},
#[error("server build `{server_metadata}` is older than the minimum supported build `{supported_metadata}`")]
BuildMetadataMismatch {
server_metadata: semver::BuildMetadata,
supported_metadata: semver::BuildMetadata,
},
#[error("The protocol or storage engine does not support live queries on this architecture")]
LiveQueriesNotSupported,
#[error("Live queries on objects not supported: {0}")]
LiveOnObject(Object),
#[error("Live queries on arrays not supported: {0}")]
LiveOnArray(Array),
#[error("Live queries on edges not supported: {0}")]
LiveOnEdges(Edges),
#[error("Query statement {0} is not a live query")]
NotLiveQuery(usize),
#[error("Query statement {0} is out of bounds")]
QueryIndexOutOfBounds(usize),
#[error("Tried to take a query response that has already been taken")]
ResponseAlreadyTaken,
#[error("Insert queries on objects not supported: {0}")]
InsertOnObject(Object),
#[error("Insert queries on arrays not supported: {0}")]
InsertOnArray(Array),
#[error("Insert queries on edges not supported: {0}")]
InsertOnEdges(Edges),
}
#[cfg(feature = "protocol-http")]
impl From<reqwest::Error> for crate::Error {
fn from(e: reqwest::Error) -> Self {
Self::Api(Error::Http(e.to_string()))
}
}
#[cfg(all(feature = "protocol-ws", not(target_arch = "wasm32")))]
#[cfg_attr(docsrs, doc(cfg(all(feature = "protocol-ws", not(target_arch = "wasm32")))))]
impl From<tokio_tungstenite::tungstenite::Error> for crate::Error {
fn from(error: tokio_tungstenite::tungstenite::Error) -> Self {
Self::Api(Error::Ws(error.to_string()))
}
}
impl<T> From<flume::SendError<T>> for crate::Error {
fn from(error: flume::SendError<T>) -> Self {
Self::Api(Error::InternalError(error.to_string()))
}
}
impl From<flume::RecvError> for crate::Error {
fn from(error: flume::RecvError) -> Self {
Self::Api(Error::InternalError(error.to_string()))
}
}
impl From<url::ParseError> for crate::Error {
fn from(error: url::ParseError) -> Self {
Self::Api(Error::InternalError(error.to_string()))
}
}
#[cfg(all(feature = "protocol-ws", target_arch = "wasm32"))]
#[cfg_attr(docsrs, doc(cfg(all(feature = "protocol-ws", target_arch = "wasm32"))))]
impl From<ws_stream_wasm::WsErr> for crate::Error {
fn from(error: ws_stream_wasm::WsErr) -> Self {
Self::Api(Error::Ws(error.to_string()))
}
}
#[cfg(all(feature = "protocol-ws", target_arch = "wasm32"))]
#[cfg_attr(docsrs, doc(cfg(all(feature = "protocol-ws", target_arch = "wasm32"))))]
impl From<pharos::PharErr> for crate::Error {
fn from(error: pharos::PharErr) -> Self {
Self::Api(Error::Ws(error.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 From<FromValueError> for crate::Error {
fn from(error: FromValueError) -> Self {
Self::Api(Error::FromValue {
value: error.value,
error: error.error,
})
}
}