risingwave_frontend/
error.rs1use risingwave_batch::error::BatchError;
16use risingwave_common::array::ArrayError;
17use risingwave_common::error::{BoxedError, NoFunction, NotImplemented};
18use risingwave_common::license::FeatureNotAvailable;
19use risingwave_common::secret::SecretError;
20use risingwave_common::session_config::SessionConfigError;
21use risingwave_common::util::value_encoding::error::ValueEncodingError;
22use risingwave_connector::error::ConnectorError;
23use risingwave_connector::sink::SinkError;
24use risingwave_expr::ExprError;
25use risingwave_pb::PbFieldNotFound;
26use risingwave_rpc_client::error::{RpcError, ToTonicStatus, TonicStatusWrapper};
27use thiserror::Error;
28use thiserror_ext::AsReport;
29use tokio::task::JoinError;
30
31use crate::expr::CastError;
32
33#[derive(Error, thiserror_ext::ReportDebug, thiserror_ext::Box, thiserror_ext::Macro)]
41#[thiserror_ext(newtype(name = RwError, backtrace), macro(path = "crate::error"))]
42pub enum ErrorCode {
43 #[error("internal error: {0}")]
44 InternalError(String),
45 #[error(transparent)]
47 Uncategorized(
48 #[from]
49 #[backtrace]
50 anyhow::Error,
51 ),
52 #[error("connector error: {0}")]
53 ConnectorError(
54 #[source]
55 #[backtrace]
56 BoxedError,
57 ),
58 #[error(transparent)]
59 NotImplemented(#[from] NotImplemented),
60 #[error("Not supported: {0}\nHINT: {1}")]
62 NotSupported(String, String),
63 #[error(transparent)]
64 NoFunction(#[from] NoFunction),
65 #[error(transparent)]
66 IoError(#[from] std::io::Error),
67 #[error("Storage error: {0}")]
68 StorageError(
69 #[backtrace]
70 #[source]
71 BoxedError,
72 ),
73 #[error("Expr error: {0}")]
74 ExprError(
75 #[source]
76 #[backtrace]
77 BoxedError,
78 ),
79 #[error("{0}")]
82 BatchError(
83 #[source]
84 #[backtrace]
85 BoxedError,
87 ),
88 #[error("Array error: {0}")]
89 ArrayError(
90 #[from]
91 #[backtrace]
92 ArrayError,
93 ),
94 #[error("Stream error: {0}")]
95 StreamError(
96 #[backtrace]
97 #[source]
98 BoxedError,
99 ),
100 #[error("{0}")]
103 RpcError(
104 #[source]
105 #[backtrace]
106 BoxedError,
108 ),
109 #[error("Bind error: {0}")]
112 BindError(#[message] String),
113 #[error("Failed to bind expression: {expr}: {error}")]
115 BindErrorRoot {
116 expr: String,
117 #[source]
118 #[backtrace]
119 error: BoxedError,
120 },
121 #[error(transparent)]
122 CastError(
123 #[from]
124 #[backtrace]
125 CastError,
126 ),
127 #[error("Catalog error: {0}")]
128 CatalogError(
129 #[source]
130 #[backtrace]
131 BoxedError,
132 ),
133 #[error("Protocol error: {0}")]
134 ProtocolError(String),
135 #[error("Scheduler error: {0}")]
136 SchedulerError(
137 #[source]
138 #[backtrace]
139 BoxedError,
140 ),
141 #[error("Task not found")]
142 TaskNotFound,
143 #[error("Session not found")]
144 SessionNotFound,
145 #[error("Item not found: {0}")]
146 ItemNotFound(String),
147 #[error("Invalid input syntax: {0}")]
148 InvalidInputSyntax(String),
149 #[error("Can not compare in memory: {0}")]
150 MemComparableError(#[from] memcomparable::Error),
151 #[error("Error while de/se values: {0}")]
152 ValueEncodingError(
153 #[from]
154 #[backtrace]
155 ValueEncodingError,
156 ),
157 #[error("Invalid value `{config_value}` for `{config_entry}`")]
158 InvalidConfigValue {
159 config_entry: String,
160 config_value: String,
161 },
162 #[error("Invalid Parameter Value: {0}")]
163 InvalidParameterValue(String),
164 #[error("Sink error: {0}")]
165 SinkError(
166 #[source]
167 #[backtrace]
168 BoxedError,
169 ),
170 #[error("Permission denied: {0}")]
171 PermissionDenied(String),
172 #[error("Failed to get/set session config: {0}")]
173 SessionConfig(
174 #[from]
175 #[backtrace]
176 SessionConfigError,
177 ),
178 #[error("Secret error: {0}")]
179 SecretError(
180 #[from]
181 #[backtrace]
182 SecretError,
183 ),
184 #[error("{0} has been deprecated, please use {1} instead.")]
185 Deprecated(String, String),
186 #[error(transparent)]
187 FeatureNotAvailable(
188 #[from]
189 #[backtrace]
190 FeatureNotAvailable,
191 ),
192}
193
194pub type Result<T> = std::result::Result<T, RwError>;
196
197impl From<TonicStatusWrapper> for RwError {
198 fn from(status: TonicStatusWrapper) -> Self {
199 use tonic::Code;
200
201 let message = status.inner().message();
202
203 match status.inner().code() {
205 Code::InvalidArgument => ErrorCode::InvalidParameterValue(message.to_owned()),
206 Code::NotFound | Code::AlreadyExists => ErrorCode::CatalogError(status.into()),
207 Code::PermissionDenied => ErrorCode::PermissionDenied(message.to_owned()),
208 Code::Cancelled => ErrorCode::SchedulerError(status.into()),
209 _ => ErrorCode::RpcError(status.into()),
210 }
211 .into()
212 }
213}
214
215impl From<RpcError> for RwError {
216 fn from(r: RpcError) -> Self {
217 match r {
218 RpcError::GrpcStatus(status) => TonicStatusWrapper::into(*status),
219 _ => ErrorCode::RpcError(r.into()).into(),
220 }
221 }
222}
223
224impl From<ExprError> for RwError {
225 fn from(s: ExprError) -> Self {
226 ErrorCode::ExprError(Box::new(s)).into()
227 }
228}
229
230impl From<SinkError> for RwError {
231 fn from(e: SinkError) -> Self {
232 ErrorCode::SinkError(Box::new(e)).into()
233 }
234}
235
236impl From<ConnectorError> for RwError {
237 fn from(e: ConnectorError) -> Self {
238 ErrorCode::ConnectorError(e.into()).into()
239 }
240}
241
242impl From<PbFieldNotFound> for RwError {
243 fn from(err: PbFieldNotFound) -> Self {
244 ErrorCode::InternalError(format!(
245 "Failed to decode prost: field not found `{}`",
246 err.0
247 ))
248 .into()
249 }
250}
251
252impl From<BatchError> for RwError {
253 fn from(s: BatchError) -> Self {
254 ErrorCode::BatchError(Box::new(s)).into()
255 }
256}
257
258impl From<JoinError> for RwError {
259 fn from(join_error: JoinError) -> Self {
260 ErrorCode::Uncategorized(join_error.into()).into()
261 }
262}
263
264impl From<BoxedError> for RwError {
266 fn from(e: BoxedError) -> Self {
267 let e = anyhow::__private::kind::BoxedKind::anyhow_kind(&e).new(e);
270 ErrorCode::Uncategorized(e).into()
271 }
272}
273
274impl From<risingwave_sqlparser::parser::ParserError> for ErrorCode {
275 fn from(e: risingwave_sqlparser::parser::ParserError) -> Self {
276 ErrorCode::InvalidInputSyntax(e.to_report_string())
277 }
278}
279
280impl From<RwError> for tonic::Status {
281 fn from(err: RwError) -> Self {
282 err.to_status(tonic::Code::Internal, "RwError")
283 }
284}