1use std::any::Any;
16use std::num::{ParseIntError, TryFromIntError};
17
18use chrono::ParseError;
19use common_error::ext::ErrorExt;
20use common_error::status_code::StatusCode;
21use common_macro::stack_trace_debug;
22use snafu::{Location, Snafu};
23
24#[derive(Snafu)]
25#[snafu(visibility(pub))]
26#[stack_trace_debug]
27pub enum Error {
28 #[snafu(display("Failed to parse string to date, raw: {}", raw))]
29 ParseDateStr {
30 raw: String,
31 #[snafu(source)]
32 error: ParseError,
33 },
34
35 #[snafu(display("Invalid date string, raw: {}", raw))]
36 InvalidDateStr {
37 raw: String,
38 #[snafu(implicit)]
39 location: Location,
40 },
41
42 #[snafu(display("Failed to parse a string into Timestamp, raw string: {}", raw))]
43 ParseTimestamp {
44 raw: String,
45 #[snafu(implicit)]
46 location: Location,
47 },
48
49 #[snafu(display("Current timestamp overflow"))]
50 TimestampOverflow {
51 #[snafu(source)]
52 error: TryFromIntError,
53 #[snafu(implicit)]
54 location: Location,
55 },
56
57 #[snafu(display("Timestamp arithmetic overflow, msg: {}", msg))]
58 ArithmeticOverflow {
59 msg: String,
60 #[snafu(implicit)]
61 location: Location,
62 },
63
64 #[snafu(display("Invalid timezone offset: {hours}:{minutes}"))]
65 InvalidTimezoneOffset {
66 hours: i32,
67 minutes: u32,
68 #[snafu(implicit)]
69 location: Location,
70 },
71
72 #[snafu(display("Invalid offset string {raw}: "))]
73 ParseOffsetStr {
74 raw: String,
75 #[snafu(source)]
76 error: ParseIntError,
77 #[snafu(implicit)]
78 location: Location,
79 },
80
81 #[snafu(display("Invalid timezone string {raw}"))]
82 ParseTimezoneName {
83 raw: String,
84 #[snafu(implicit)]
85 location: Location,
86 },
87
88 #[snafu(display("Failed to format, pattern: {}", pattern))]
89 Format {
90 pattern: String,
91 #[snafu(source)]
92 error: std::fmt::Error,
93 #[snafu(implicit)]
94 location: Location,
95 },
96
97 #[snafu(display("Failed to parse duration"))]
98 ParseDuration {
99 #[snafu(source)]
100 error: humantime::DurationError,
101 #[snafu(implicit)]
102 location: Location,
103 },
104
105 #[snafu(display("Database's TTL can't be `instant`"))]
106 InvalidDatabaseTtl {
107 #[snafu(implicit)]
108 location: Location,
109 },
110}
111
112impl ErrorExt for Error {
113 fn status_code(&self) -> StatusCode {
114 match self {
115 Error::ParseDateStr { .. }
116 | Error::ParseDuration { .. }
117 | Error::InvalidDatabaseTtl { .. }
118 | Error::ParseTimestamp { .. }
119 | Error::InvalidTimezoneOffset { .. }
120 | Error::Format { .. }
121 | Error::ParseOffsetStr { .. }
122 | Error::ParseTimezoneName { .. } => StatusCode::InvalidArguments,
123 Error::TimestampOverflow { .. } => StatusCode::Internal,
124 Error::InvalidDateStr { .. } | Error::ArithmeticOverflow { .. } => {
125 StatusCode::InvalidArguments
126 }
127 }
128 }
129
130 fn as_any(&self) -> &dyn Any {
131 self
132 }
133}
134
135pub type Result<T> = std::result::Result<T, Error>;