common_time/
error.rs

1// Copyright 2023 Greptime Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use 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>;