common_grpc/
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::io;
17
18use common_error::ext::ErrorExt;
19use common_error::status_code::StatusCode;
20use common_macro::stack_trace_debug;
21use datatypes::arrow::error::ArrowError;
22use snafu::{Location, Snafu};
23
24pub type Result<T> = std::result::Result<T, Error>;
25
26#[derive(Snafu)]
27#[snafu(visibility(pub))]
28#[stack_trace_debug]
29pub enum Error {
30    #[snafu(display("Invalid client tls config, {}", msg))]
31    InvalidTlsConfig { msg: String },
32
33    #[snafu(display("Invalid config file path"))]
34    InvalidConfigFilePath {
35        #[snafu(source)]
36        error: io::Error,
37        #[snafu(implicit)]
38        location: Location,
39    },
40
41    #[snafu(display("Failed to watch config file"))]
42    FileWatch {
43        #[snafu(source)]
44        source: common_config::error::Error,
45        #[snafu(implicit)]
46        location: Location,
47    },
48
49    #[snafu(display(
50        "Write type mismatch, column name: {}, expected: {}, actual: {}",
51        column_name,
52        expected,
53        actual
54    ))]
55    TypeMismatch {
56        column_name: String,
57        expected: String,
58        actual: String,
59        #[snafu(implicit)]
60        location: Location,
61    },
62
63    #[snafu(display("Failed to create gRPC channel from '{addr}'"))]
64    CreateChannel {
65        addr: String,
66        #[snafu(source)]
67        error: tonic::transport::Error,
68        #[snafu(implicit)]
69        location: Location,
70    },
71
72    #[snafu(display("Failed to convert Arrow type: {}", from))]
73    Conversion {
74        from: String,
75        #[snafu(implicit)]
76        location: Location,
77    },
78
79    #[snafu(display("Failed to decode FlightData"))]
80    DecodeFlightData {
81        #[snafu(source)]
82        error: api::DecodeError,
83        #[snafu(implicit)]
84        location: Location,
85    },
86
87    #[snafu(display("Invalid FlightData, reason: {}", reason))]
88    InvalidFlightData {
89        reason: String,
90        #[snafu(implicit)]
91        location: Location,
92    },
93
94    #[snafu(display("Not supported: {}", feat))]
95    NotSupported { feat: String },
96
97    #[snafu(display("Failed to serde Json"))]
98    SerdeJson {
99        #[snafu(source)]
100        error: serde_json::error::Error,
101        #[snafu(implicit)]
102        location: Location,
103    },
104
105    #[snafu(display("Failed arrow operation"))]
106    Arrow {
107        #[snafu(implicit)]
108        location: Location,
109        #[snafu(source)]
110        error: ArrowError,
111    },
112}
113
114impl ErrorExt for Error {
115    fn status_code(&self) -> StatusCode {
116        match self {
117            Error::InvalidTlsConfig { .. }
118            | Error::InvalidConfigFilePath { .. }
119            | Error::FileWatch { .. }
120            | Error::TypeMismatch { .. }
121            | Error::InvalidFlightData { .. }
122            | Error::NotSupported { .. } => StatusCode::InvalidArguments,
123
124            Error::CreateChannel { .. }
125            | Error::Conversion { .. }
126            | Error::DecodeFlightData { .. }
127            | Error::SerdeJson { .. } => StatusCode::Internal,
128
129            Error::Arrow { .. } => StatusCode::Internal,
130        }
131    }
132
133    fn as_any(&self) -> &dyn Any {
134        self
135    }
136}