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(
42        "Write type mismatch, column name: {}, expected: {}, actual: {}",
43        column_name,
44        expected,
45        actual
46    ))]
47    TypeMismatch {
48        column_name: String,
49        expected: String,
50        actual: String,
51        #[snafu(implicit)]
52        location: Location,
53    },
54
55    #[snafu(display("Failed to create gRPC channel from '{addr}'"))]
56    CreateChannel {
57        addr: String,
58        #[snafu(source)]
59        error: tonic::transport::Error,
60        #[snafu(implicit)]
61        location: Location,
62    },
63
64    #[snafu(display("Failed to convert Arrow type: {}", from))]
65    Conversion {
66        from: String,
67        #[snafu(implicit)]
68        location: Location,
69    },
70
71    #[snafu(display("Failed to decode FlightData"))]
72    DecodeFlightData {
73        #[snafu(source)]
74        error: api::DecodeError,
75        #[snafu(implicit)]
76        location: Location,
77    },
78
79    #[snafu(display("Invalid FlightData, reason: {}", reason))]
80    InvalidFlightData {
81        reason: String,
82        #[snafu(implicit)]
83        location: Location,
84    },
85
86    #[snafu(display("Not supported: {}", feat))]
87    NotSupported { feat: String },
88
89    #[snafu(display("Failed to serde Json"))]
90    SerdeJson {
91        #[snafu(source)]
92        error: serde_json::error::Error,
93        #[snafu(implicit)]
94        location: Location,
95    },
96
97    #[snafu(display("Failed arrow operation"))]
98    Arrow {
99        #[snafu(implicit)]
100        location: Location,
101        #[snafu(source)]
102        error: ArrowError,
103    },
104}
105
106impl ErrorExt for Error {
107    fn status_code(&self) -> StatusCode {
108        match self {
109            Error::InvalidTlsConfig { .. }
110            | Error::InvalidConfigFilePath { .. }
111            | Error::TypeMismatch { .. }
112            | Error::InvalidFlightData { .. }
113            | Error::NotSupported { .. } => StatusCode::InvalidArguments,
114
115            Error::CreateChannel { .. }
116            | Error::Conversion { .. }
117            | Error::DecodeFlightData { .. }
118            | Error::SerdeJson { .. } => StatusCode::Internal,
119
120            Error::Arrow { .. } => StatusCode::Internal,
121        }
122    }
123
124    fn as_any(&self) -> &dyn Any {
125        self
126    }
127}