diff --git a/datafusion/src/error.rs b/datafusion/src/error.rs index bf9df5077c908..b7a8f45b2e674 100644 --- a/datafusion/src/error.rs +++ b/datafusion/src/error.rs @@ -74,6 +74,8 @@ pub enum DataFusionError { impl DataFusionError { /// Wraps this [DataFusionError] as an [arrow::error::ArrowError]. + /// + /// TODO this can be removed in favor if the conversion below pub fn into_arrow_external_error(self) -> ArrowError { ArrowError::from_external_error(Box::new(self)) } @@ -91,6 +93,16 @@ impl From for DataFusionError { } } +impl From for ArrowError { + fn from(e: DataFusionError) -> Self { + match e { + DataFusionError::ArrowError(e) => e, + DataFusionError::External(e) => ArrowError::ExternalError(e), + other => ArrowError::ExternalError(Box::new(other)), + } + } +} + impl From for DataFusionError { fn from(e: ParquetError) -> Self { DataFusionError::ParquetError(e) @@ -155,3 +167,42 @@ impl Display for DataFusionError { } impl error::Error for DataFusionError {} + +#[cfg(test)] +mod test { + use crate::error::DataFusionError; + use arrow::error::ArrowError; + + #[test] + fn arrow_error_to_datafusion() { + let res = return_arrow_error().unwrap_err(); + assert_eq!( + res.to_string(), + "External error: Error during planning: foo" + ); + } + + #[test] + fn datafusion_error_to_arrow() { + let res = return_datafusion_error().unwrap_err(); + assert_eq!(res.to_string(), "Arrow error: Schema error: bar"); + } + + /// Model what happens when implementing SendableRecrordBatchStream: + /// DataFusion code needs to return an ArrowError + #[allow(clippy::try_err)] + fn return_arrow_error() -> arrow::error::Result<()> { + // Expect the '?' to work + let _foo = Err(DataFusionError::Plan("foo".to_string()))?; + Ok(()) + } + + /// Model what happens when using arrow kernels in DataFusion + /// code: need to turn an ArrowError into a DataFusionError + #[allow(clippy::try_err)] + fn return_datafusion_error() -> crate::error::Result<()> { + // Expect the '?' to work + let _bar = Err(ArrowError::SchemaError("bar".to_string()))?; + Ok(()) + } +}