1use std::fmt::Debug;
2
3use graft_core::{page::PageSizeErr, page_idx::ConvertToPageIdxErr};
4use graft_proto::common::v1::{GraftErr, GraftErrCode};
5use thiserror::Error;
6
7use crate::runtime::storage;
8
9#[derive(Error, Debug)]
10pub enum ClientErr {
11 #[error("graft error: {0}")]
12 GraftErr(#[from] GraftErr),
13
14 #[error("http request failed: {0}")]
15 HttpErr(#[from] ureq::Error),
16
17 #[error("failed to decode protobuf message")]
18 ProtobufDecodeErr,
19
20 #[error("failed to parse splinter: {0}")]
21 SplinterParseErr(#[from] splinter_rs::DecodeErr),
22
23 #[error("local storage error: {0}")]
24 StorageErr(#[from] storage::StorageErr),
25
26 #[error("io error: {0}")]
27 IoErr(std::io::ErrorKind),
28
29 #[error("invalid page index")]
30 ConvertToPageIdxErr(#[from] ConvertToPageIdxErr),
31
32 #[error("invalid page size")]
33 PageSizeErr(#[from] PageSizeErr),
34}
35
36impl From<http::Error> for ClientErr {
37 fn from(err: http::Error) -> Self {
38 Self::HttpErr(err.into())
39 }
40}
41
42impl From<std::io::Error> for ClientErr {
43 fn from(err: std::io::Error) -> Self {
44 match ureq::Error::from(err) {
46 ureq::Error::Io(ioerr) => Self::IoErr(ioerr.kind()),
48 ureq::Error::Decompress(_, ioerr) => ioerr.into(),
50 other => Self::HttpErr(other),
52 }
53 }
54}
55
56impl From<prost::DecodeError> for ClientErr {
57 fn from(_: prost::DecodeError) -> Self {
58 ClientErr::ProtobufDecodeErr
59 }
60}
61
62impl ClientErr {
63 pub(crate) fn is_snapshot_missing(&self) -> bool {
64 match self {
65 Self::GraftErr(err) => err.code() == GraftErrCode::SnapshotMissing,
66 _ => false,
67 }
68 }
69
70 pub(crate) fn is_commit_rejected(&self) -> bool {
71 match self {
72 Self::GraftErr(err) => err.code() == GraftErrCode::CommitRejected,
73 _ => false,
74 }
75 }
76
77 pub(crate) fn is_auth_err(&self) -> bool {
78 match self {
79 Self::GraftErr(err) => err.code() == GraftErrCode::Unauthorized,
80 _ => false,
81 }
82 }
83
84 pub(crate) fn is_network_err(&self) -> bool {
85 match self {
86 Self::HttpErr(ureq::Error::Timeout(_)) => true,
87 Self::HttpErr(ureq::Error::ConnectionFailed) => true,
88 Self::HttpErr(ureq::Error::ConnectProxyFailed(_)) => true,
89 Self::HttpErr(ureq::Error::Io(_)) => true,
90 Self::GraftErr(err) => err.code() == GraftErrCode::ServiceUnavailable,
91 _ => false,
92 }
93 }
94}