Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(error): simplify leaf error instantiation #13627

Merged
merged 9 commits into from
Nov 28, 2023
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ arrow-flight = "49"
arrow-select = "49"
arrow-ord = "49"
arrow-row = "49"
thiserror-ext = "0.0.7"
thiserror-ext = "0.0.8"
tikv-jemalloc-ctl = { git = "https://github.com/risingwavelabs/jemallocator.git", rev = "64a2d9" }
tikv-jemallocator = { git = "https://github.com/risingwavelabs/jemallocator.git", features = [
"profiling",
Expand Down
22 changes: 22 additions & 0 deletions e2e_test/error_ui/simple/main.slt
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,25 @@ db error: ERROR: Failed to run the query
Caused by these errors (recent errors listed first):
1: Expr error
2: Division by zero


statement error
set rw_implicit_flush to maybe;
----
db error: ERROR: Failed to run the query

Caused by these errors (recent errors listed first):
1: Failed to get/set session config
2: Invalid value `maybe` for `rw_implicit_flush`
3: provided string was not `true` or `false`
Comment on lines +63 to +71
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forget to add tests in last PR (#13588).



statement error
set transaction_isolation_level to read_committed;
----
db error: ERROR: Failed to run the query

Caused by these errors (recent errors listed first):
1: Failed to get/set session config
2: Invalid value `read_committed` for `transaction_isolation_level`
3: Feature is not yet implemented: isolation level. Tracking issue: https://github.com/risingwavelabs/risingwave/issues/10736
35 changes: 23 additions & 12 deletions src/common/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use memcomparable::Error as MemComparableError;
use risingwave_error::tonic::{ToTonicStatus, TonicStatusWrapper};
use risingwave_pb::PbFieldNotFound;
use thiserror::Error;
use thiserror_ext::Macro;
use tokio::task::JoinError;

use crate::array::ArrayError;
Expand All @@ -36,7 +37,7 @@ pub type BoxedError = Box<dyn Error>;

pub use anyhow::anyhow as anyhow_error;

#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, Default)]
pub struct TrackingIssue(Option<u32>);

impl TrackingIssue {
Expand Down Expand Up @@ -70,6 +71,15 @@ impl Display for TrackingIssue {
}
}

#[derive(Error, Debug, Macro)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Macro isn't a very cool name 😕

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have any proposals? 😢 It's not stable, so feel free to change.

#[error("Feature is not yet implemented: {feature}. {issue}")]
#[thiserror_ext(macro(path = "crate::error"))]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is because we want the qualified name when calling from other crates to avoid importing the structure itself. So we generate the path $crate::error:: before the type name.

If the structure is private, then path is not necessary.

BTW, is there any way to automatically derive this?

Copy link
Member

@xxchan xxchan Nov 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does module_path!() work?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't find a way. 😕 Calling module_path in the proc macro body won't work as we will get the module path of the proc macro crate.

pub struct NotImplemented {
#[message]
pub feature: String,
pub issue: TrackingIssue,
}

#[derive(Error, Debug)]
pub enum ErrorCode {
#[error("internal error: {0}")]
Expand All @@ -87,8 +97,8 @@ pub enum ErrorCode {
#[backtrace]
BoxedError,
),
#[error("Feature is not yet implemented: {0}\n{1}")]
NotImplemented(String, TrackingIssue),
#[error(transparent)]
NotImplemented(#[from] NotImplemented),
// Tips: Use this only if it's intended to reject the query
#[error("Not supported: {0}\nHINT: {1}")]
NotSupported(String, String),
Expand Down Expand Up @@ -200,6 +210,13 @@ pub enum ErrorCode {
),
}

// TODO(error-handling): automatically generate this impl.
impl From<NotImplemented> for RwError {
fn from(value: NotImplemented) -> Self {
ErrorCode::from(value).into()
}
}

pub fn internal_error(msg: impl Into<String>) -> RwError {
ErrorCode::InternalError(msg.into()).into()
}
Expand Down Expand Up @@ -479,14 +496,8 @@ macro_rules! ensure_eq {

#[macro_export]
macro_rules! bail {
($msg:literal $(,)?) => {
return Err($crate::error::anyhow_error!($msg).into())
};
($err:expr $(,)?) => {
return Err($crate::error::anyhow_error!($err).into())
};
($fmt:expr, $($arg:tt)*) => {
return Err($crate::error::anyhow_error!($fmt, $($arg)*).into())
($($arg:tt)*) => {
return Err($crate::error::anyhow_error!($($arg)*).into())
};
}

Expand Down Expand Up @@ -616,7 +627,7 @@ mod tests {
check_grpc_error(ErrorCode::TaskNotFound, Code::Internal);
check_grpc_error(ErrorCode::InternalError(String::new()), Code::Internal);
check_grpc_error(
ErrorCode::NotImplemented(String::new(), None.into()),
ErrorCode::NotImplemented(not_implemented!("test")),
Code::Internal,
);
}
Expand Down
6 changes: 4 additions & 2 deletions src/common/src/session_config/transaction_isolation_level.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
use std::fmt::Formatter;
use std::str::FromStr;

use crate::error::{bail_not_implemented, NotImplemented};

#[derive(Copy, Default, Debug, Clone, PartialEq, Eq)]
// Some variants are never constructed so allow dead code here.
#[allow(dead_code)]
Expand All @@ -27,10 +29,10 @@ pub enum IsolationLevel {
}

impl FromStr for IsolationLevel {
type Err = &'static str;
type Err = NotImplemented;

fn from_str(_s: &str) -> Result<Self, Self::Err> {
Err("isolation level is not yet supported")
bail_not_implemented!(issue = 10736, "isolation level");
}
}

Expand Down
19 changes: 7 additions & 12 deletions src/common/src/types/to_binary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@ use bytes::{Bytes, BytesMut};
use postgres_types::{ToSql, Type};

use super::{DataType, DatumRef, ScalarRefImpl, F32, F64};
use crate::error::TrackingIssue;
use crate::error::NotImplemented;

/// Error type for [`ToBinary`] trait.
#[derive(thiserror::Error, Debug)]
pub enum ToBinaryError {
#[error(transparent)]
ToSql(Box<dyn std::error::Error + Send + Sync>),

#[error("Feature is not yet implemented: {0}\n{1}")]
NotImplemented(String, TrackingIssue),
#[error(transparent)]
NotImplemented(#[from] NotImplemented),
}

pub type Result<T> = std::result::Result<T, ToBinaryError>;
Expand Down Expand Up @@ -87,15 +87,10 @@ impl ToBinary for ScalarRefImpl<'_> {
ScalarRefImpl::Time(v) => v.to_binary_with_type(ty),
ScalarRefImpl::Bytea(v) => v.to_binary_with_type(ty),
ScalarRefImpl::Jsonb(v) => v.to_binary_with_type(ty),
ScalarRefImpl::Struct(_) | ScalarRefImpl::List(_) => {
Err(ToBinaryError::NotImplemented(
format!(
"the pgwire extended-mode encoding for {} is unsupported",
ty
),
Some(7949).into(),
))
}
ScalarRefImpl::Struct(_) | ScalarRefImpl::List(_) => bail_not_implemented!(
issue = 7949,
"the pgwire extended-mode encoding for {ty} is unsupported"
),
}
}
}
Expand Down
7 changes: 2 additions & 5 deletions src/frontend/src/binder/expr/binary_op.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use risingwave_common::bail_not_implemented;
use risingwave_common::error::{ErrorCode, Result};
use risingwave_common::types::DataType;
use risingwave_sqlparser::ast::{BinaryOperator, Expr};
Expand Down Expand Up @@ -186,11 +187,7 @@ impl Binder {
func_types.push(ExprType::Not);
ExprType::RegexpEq
}
_ => {
return Err(
ErrorCode::NotImplemented(format!("binary op: {:?}", op), 112.into()).into(),
)
}
_ => bail_not_implemented!(issue = 112, "binary op: {:?}", op),
};
func_types.push(final_type);
Ok(func_types)
Expand Down
Loading
Loading