mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-01-08 06:12:55 +00:00
feat: Add as_any() to opaque error
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
use std::any::Any;
|
||||
|
||||
use crate::status_code::StatusCode;
|
||||
|
||||
/// Extension to [`Error`](std::error::Error) in std.
|
||||
@@ -11,6 +13,10 @@ pub trait ErrorExt: std::error::Error {
|
||||
// Add `_opt` suffix to avoid confusing with similar method in `std::error::Error`, once backtrace
|
||||
// in std is stable, we can deprecate this method.
|
||||
fn backtrace_opt(&self) -> Option<&crate::snafu::Backtrace>;
|
||||
|
||||
/// Returns the error as [Any](std::any::Any) so that it can be
|
||||
/// downcast to a specific implementation.
|
||||
fn as_any(&self) -> &dyn Any;
|
||||
}
|
||||
|
||||
/// A helper macro to define a opaque boxed error based on errors that implement [ErrorExt] trait.
|
||||
@@ -61,6 +67,10 @@ macro_rules! define_opaque_error {
|
||||
fn backtrace_opt(&self) -> Option<&$crate::snafu::Backtrace> {
|
||||
self.inner.backtrace_opt()
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn std::any::Any {
|
||||
self.inner.as_any()
|
||||
}
|
||||
}
|
||||
|
||||
// Implement ErrorCompat for this opaque error so the backtrace is also available
|
||||
@@ -104,6 +114,10 @@ mod tests {
|
||||
fn backtrace_opt(&self) -> Option<&snafu::Backtrace> {
|
||||
ErrorCompat::backtrace(self)
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl From<InnerError> for Error {
|
||||
@@ -150,6 +164,8 @@ mod tests {
|
||||
assert_eq!("This is a leaf error, val: 10", err.to_string());
|
||||
assert_eq!(StatusCode::Internal, err.status_code());
|
||||
|
||||
err.as_any().downcast_ref::<InnerError>().unwrap();
|
||||
|
||||
// Test internal error.
|
||||
let err: Error = throw_internal().map_err(Into::into).err().unwrap();
|
||||
let msg = format!("{:?}", err);
|
||||
@@ -163,5 +179,7 @@ mod tests {
|
||||
assert!(err.backtrace_opt().is_some());
|
||||
assert_eq!("This is an internal error", err.to_string());
|
||||
assert_eq!(StatusCode::Internal, err.status_code());
|
||||
|
||||
err.as_any().downcast_ref::<InnerError>().unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@ impl<'a, E: ErrorExt + ?Sized> fmt::Debug for DebugFormat<'a, E> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::any::Any;
|
||||
|
||||
use snafu::{prelude::*, Backtrace, GenerateImplicitData};
|
||||
|
||||
use super::*;
|
||||
@@ -42,6 +44,10 @@ mod tests {
|
||||
fn backtrace_opt(&self) -> Option<&Backtrace> {
|
||||
None
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Snafu)]
|
||||
@@ -54,6 +60,10 @@ mod tests {
|
||||
fn backtrace_opt(&self) -> Option<&Backtrace> {
|
||||
Some(&self.backtrace)
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Snafu)]
|
||||
@@ -68,6 +78,10 @@ mod tests {
|
||||
fn backtrace_opt(&self) -> Option<&Backtrace> {
|
||||
Some(&self.backtrace)
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
//! Utils for mock.
|
||||
|
||||
use std::any::Any;
|
||||
use std::fmt;
|
||||
|
||||
use snafu::GenerateImplicitData;
|
||||
@@ -51,6 +52,10 @@ impl ErrorExt for MockError {
|
||||
fn backtrace_opt(&self) -> Option<&Backtrace> {
|
||||
self.backtrace.as_ref()
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl ErrorCompat for MockError {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use std::any::Any;
|
||||
|
||||
use common_error::prelude::*;
|
||||
|
||||
/// Business error of datanode.
|
||||
@@ -36,6 +38,10 @@ impl ErrorExt for Error {
|
||||
fn backtrace_opt(&self) -> Option<&Backtrace> {
|
||||
ErrorCompat::backtrace(self)
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -31,6 +31,10 @@ impl ErrorExt for InnerError {
|
||||
fn backtrace_opt(&self) -> Option<&Backtrace> {
|
||||
ErrorCompat::backtrace(self)
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl From<InnerError> for Error {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use std::any::Any;
|
||||
|
||||
use common_error::prelude::*;
|
||||
use datafusion::error::DataFusionError;
|
||||
|
||||
@@ -49,6 +51,10 @@ impl ErrorExt for InnerError {
|
||||
fn backtrace_opt(&self) -> Option<&Backtrace> {
|
||||
ErrorCompat::backtrace(self)
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl From<InnerError> for Error {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use std::any::Any;
|
||||
|
||||
use common_error::prelude::*;
|
||||
use sqlparser::parser::ParserError;
|
||||
|
||||
@@ -42,6 +44,10 @@ impl ErrorExt for Error {
|
||||
fn backtrace_opt(&self) -> Option<&Backtrace> {
|
||||
ErrorCompat::backtrace(self)
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use std::any::Any;
|
||||
|
||||
use common_error::prelude::*;
|
||||
use datafusion::error::DataFusionError;
|
||||
|
||||
@@ -29,6 +31,10 @@ impl ErrorExt for InnerError {
|
||||
fn backtrace_opt(&self) -> Option<&Backtrace> {
|
||||
ErrorCompat::backtrace(self)
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl From<InnerError> for Error {
|
||||
|
||||
Reference in New Issue
Block a user