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