couchbase_lite/
error.rs

1use crate::ffi::{
2    c4error_getDescription, c4error_getMessage, C4Error, C4ErrorDomain, FLSliceResult,
3};
4use std::{fmt, os::raw::c_int};
5
6/// Enum listing possible errors.
7pub enum Error {
8    /// couchbase-lite-core error
9    C4Error(C4Error),
10    /// UTF-8 decoding problem
11    InvalidUtf8,
12    /// some invariant was broken
13    LogicError(Box<str>),
14    SerdeFleece(serde_fleece::Error),
15    /// argument contains 0 character
16    NulError(std::ffi::NulError),
17    InvalidQuery {
18        err: C4Error,
19        query_expr: Box<str>,
20        pos: c_int,
21    },
22}
23
24impl std::error::Error for Error {}
25
26pub(crate) type Result<T> = std::result::Result<T, Error>;
27
28impl fmt::Display for Error {
29    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
30        match self {
31            Error::C4Error(err) => {
32                let (msg, desc) = into_msg_desc(*err);
33                write!(
34                    fmt,
35                    "c4 error {}: {}",
36                    desc.as_utf8_lossy(),
37                    msg.as_utf8_lossy()
38                )
39            }
40            Error::InvalidUtf8 => fmt.write_str("Utf8 encoding error"),
41            Error::LogicError(msg) => write!(fmt, "logic error: {msg}"),
42            Error::SerdeFleece(err) => write!(fmt, "serde+flecce error: {err}"),
43            Error::NulError(err) => write!(fmt, "argument contains null character: {err}"),
44            Error::InvalidQuery {
45                pos,
46                query_expr,
47                err,
48            } => {
49                let (msg, desc) = into_msg_desc(*err);
50                write!(
51                    fmt,
52                    "Can not parse query {}, error at {}: {} {}",
53                    query_expr,
54                    pos,
55                    desc.as_utf8_lossy(),
56                    msg.as_utf8_lossy()
57                )
58            }
59        }
60    }
61}
62
63impl fmt::Debug for Error {
64    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
65        match self {
66            Error::C4Error(err) => {
67                let (msg, desc) = into_msg_desc(*err);
68                write!(
69                    fmt,
70                    "{:?} /  {}: {}",
71                    *err,
72                    desc.as_utf8_lossy(),
73                    msg.as_utf8_lossy()
74                )
75            }
76            Error::InvalidUtf8 => write!(fmt, "Invalid UTF-8 error"),
77            Error::LogicError(msg) => write!(fmt, "LogicError: {msg}"),
78            Error::SerdeFleece(err) => write!(fmt, "SerdeFleece error: {err}"),
79            Error::NulError(err) => write!(fmt, "NulError: {err:?}"),
80            Error::InvalidQuery {
81                pos,
82                query_expr,
83                err,
84            } => {
85                let (msg, desc) = into_msg_desc(*err);
86                write!(
87                    fmt,
88                    "InvalidQuery {{ query_expr {}, pos {}, err {:?} / {}: {} }}",
89                    query_expr,
90                    pos,
91                    *err,
92                    desc.as_utf8_lossy(),
93                    msg.as_utf8_lossy()
94                )
95            }
96        }
97    }
98}
99
100impl From<C4Error> for Error {
101    fn from(err: C4Error) -> Self {
102        Error::C4Error(err)
103    }
104}
105
106impl From<serde_fleece::Error> for Error {
107    fn from(err: serde_fleece::Error) -> Self {
108        Error::SerdeFleece(err)
109    }
110}
111
112impl From<std::ffi::NulError> for Error {
113    fn from(err: std::ffi::NulError) -> Self {
114        Error::NulError(err)
115    }
116}
117
118pub(crate) fn c4error_init() -> C4Error {
119    C4Error {
120        domain: C4ErrorDomain::kC4MaxErrorDomainPlus1,
121        code: 0,
122        internal_info: 0,
123    }
124}
125
126fn into_msg_desc(err: C4Error) -> (FLSliceResult, FLSliceResult) {
127    let msg = unsafe { c4error_getMessage(err) };
128    let desc = unsafe { c4error_getDescription(err) };
129    (msg, desc)
130}