1use std::error::Error as StdError;
2
3use crate::types::ColumnType;
4
5#[derive(Debug, thiserror::Error)]
7#[non_exhaustive]
8#[allow(missing_docs)]
9pub enum Error {
10 #[error("invalid params: {0}")]
11 InvalidParams(#[source] Box<dyn StdError + Send + Sync>),
12 #[error("network error: {0:?}")]
13 Network(#[from] hyper::Error),
14 #[error("invalid utf-8: {0}")]
15 InvalidUnicode(#[from] std::string::FromUtf8Error),
16 #[error("no rows returned by a query that expected to return at least one row")]
17 RowNotFound,
18 #[error("sequences must have a known size ahead of time")]
19 SequenceMustHaveLength,
20 #[error("`deserialize_any` is not supported")]
21 NotEnoughData,
22 #[error("tag for enum is not valid")]
23 InvalidTagEncoding(usize),
24 #[error("bad response: {0}")]
25 BadResponse(String),
26 #[error("Unsupported column type: {0}")]
27 UnsupportedColumn(String),
28 #[error("Column types mismatch: {schema:?} vs {row:?}")]
29 WrongColumnTypes {
30 schema: Vec<ColumnType>,
31 row: Vec<ColumnType>,
32 },
33 #[error("Column names mismatch: {schema:?} vs {row:?}")]
34 WrongColumnNames {
35 schema: Vec<&'static str>,
36 row: Box<[String]>,
37 },
38 #[error("Each column must have a name: {row:?}")]
39 MissingColumnName { row: Vec<&'static str> },
40
41 #[error("internal error: too small buffer, need another {0} bytes")]
44 #[doc(hidden)]
45 TooSmallBuffer(usize),
46}
47
48impl Error {
49 pub async fn from_bad_response(response: hyper::Response<hyper::Body>) -> Self {
50 let status = response.status();
51 let raw_bytes = match hyper::body::to_bytes(response.into_body()).await {
52 Ok(bytes) => bytes,
53 Err(err) => return err.into(),
54 };
55 let reason = String::from_utf8(raw_bytes.into())
56 .map(|reason| reason.trim().into())
57 .unwrap_or_else(|_| {
58 format!(
60 "{} {}",
61 status.as_str(),
62 status.canonical_reason().unwrap_or("<unknown>"),
63 )
64 });
65
66 Error::BadResponse(reason)
67 }
68}