1use std::any::Any;
16
17use common_error::ext::ErrorExt;
18use common_error::status_code::StatusCode;
19use common_macro::stack_trace_debug;
20use datafusion::error::DataFusionError;
21use log_query::LogExpr;
22use snafu::{Location, Snafu};
23
24#[derive(Snafu)]
25#[snafu(visibility(pub))]
26#[stack_trace_debug]
27pub enum Error {
28 #[snafu(display("General catalog error"))]
29 Catalog {
30 #[snafu(implicit)]
31 location: Location,
32 source: catalog::error::Error,
33 },
34
35 #[snafu(display("Internal error during building DataFusion plan"))]
36 DataFusionPlanning {
37 #[snafu(source)]
38 error: datafusion::error::DataFusionError,
39 #[snafu(implicit)]
40 location: Location,
41 },
42
43 #[snafu(display("Unknown table type, downcast failed"))]
44 UnknownTable {
45 #[snafu(implicit)]
46 location: Location,
47 },
48
49 #[snafu(display("Cannot find time index column"))]
50 TimeIndexNotFound {
51 #[snafu(implicit)]
52 location: Location,
53 },
54
55 #[snafu(display("Unimplemented feature: {}", feature))]
56 Unimplemented {
57 #[snafu(implicit)]
58 location: Location,
59 feature: String,
60 },
61
62 #[snafu(display("Unknown aggregate function: {name}"))]
63 UnknownAggregateFunction {
64 name: String,
65 #[snafu(implicit)]
66 location: Location,
67 },
68
69 #[snafu(display("Unknown scalar function: {name}"))]
70 UnknownScalarFunction {
71 name: String,
72 #[snafu(implicit)]
73 location: Location,
74 },
75
76 #[snafu(display("Unexpected log expression: {expr:?}, expected {expected}"))]
77 UnexpectedLogExpr {
78 expr: LogExpr,
79 expected: String,
80 #[snafu(implicit)]
81 location: Location,
82 },
83}
84
85impl ErrorExt for Error {
86 fn status_code(&self) -> StatusCode {
87 use Error::*;
88 match self {
89 Catalog { source, .. } => source.status_code(),
90 DataFusionPlanning { .. } => StatusCode::External,
91 UnknownTable { .. } | TimeIndexNotFound { .. } => StatusCode::Internal,
92 Unimplemented { .. } => StatusCode::Unsupported,
93 UnknownAggregateFunction { .. }
94 | UnknownScalarFunction { .. }
95 | UnexpectedLogExpr { .. } => StatusCode::InvalidArguments,
96 }
97 }
98
99 fn as_any(&self) -> &dyn Any {
100 self
101 }
102}
103
104pub type Result<T> = std::result::Result<T, Error>;
105
106impl From<Error> for DataFusionError {
107 fn from(err: Error) -> Self {
108 DataFusionError::External(Box::new(err))
109 }
110}