@@ -482,6 +482,11 @@ impl DataFusionError {
482482 "" . to_owned ( )
483483 }
484484
485+ /// Return a [`DataFusionErrorBuilder`] to build a [`DataFusionError`]
486+ pub fn builder ( ) -> DataFusionErrorBuilder {
487+ DataFusionErrorBuilder :: default ( )
488+ }
489+
485490 fn error_prefix ( & self ) -> & ' static str {
486491 match self {
487492 DataFusionError :: ArrowError ( _, _) => "Arrow error: " ,
@@ -616,6 +621,9 @@ impl DataFusionError {
616621 DiagnosticsIterator { head : self } . next ( )
617622 }
618623
624+ /// Return an iterator over this [`DataFusionError`] and any other
625+ /// [`DataFusionError`]s in a [`DataFusionError::Collection`].
626+ ///
619627 /// Sometimes DataFusion is able to collect multiple errors in a SQL query
620628 /// before terminating, e.g. across different expressions in a SELECT
621629 /// statements or different sides of a UNION. This method returns an
@@ -648,17 +656,65 @@ impl DataFusionError {
648656 }
649657}
650658
659+ /// A builder for [`DataFusionError`]
660+ ///
661+ /// This builder can be used to collect multiple errors and return them as a
662+ /// [`DataFusionError::Collection`].
663+ ///
664+ /// # Example: no errors
665+ /// ```
666+ /// # use datafusion_common::DataFusionError;
667+ /// let mut builder = DataFusionError::builder();
668+ /// // ok_or returns the value if no errors have been added
669+ /// assert_eq!(builder.error_or(42).unwrap(), 42);
670+ /// ```
671+ ///
672+ /// # Example: with errors
673+ /// ```
674+ /// # use datafusion_common::{assert_contains, DataFusionError};
675+ /// let mut builder = DataFusionError::builder();
676+ /// builder.add_error(DataFusionError::Internal("foo".to_owned()));
677+ /// // ok_or returns the value if no errors have been added
678+ /// assert_contains!(builder.error_or(42).unwrap_err().to_string(), "Internal error: foo");
679+ /// ```
680+ #[ derive( Debug , Default ) ]
651681pub struct DataFusionErrorBuilder ( Vec < DataFusionError > ) ;
652682
653683impl DataFusionErrorBuilder {
684+ /// Create a new [`DataFusionErrorBuilder`]
654685 pub fn new ( ) -> Self {
655- Self ( Vec :: new ( ) )
686+ Default :: default ( )
656687 }
657688
689+ /// Add an error to the in progress list
690+ ///
691+ /// # Example
692+ /// ```
693+ /// # use datafusion_common::{assert_contains, DataFusionError};
694+ /// let mut builder = DataFusionError::builder();
695+ /// builder.add_error(DataFusionError::Internal("foo".to_owned()));
696+ /// assert_contains!(builder.error_or(42).unwrap_err().to_string(), "Internal error: foo");
697+ /// ```
658698 pub fn add_error ( & mut self , error : DataFusionError ) {
659699 self . 0 . push ( error) ;
660700 }
661701
702+ /// Add an error to the in progress list, returning the builder
703+ ///
704+ /// # Example
705+ /// ```
706+ /// # use datafusion_common::{assert_contains, DataFusionError};
707+ /// let builder = DataFusionError::builder()
708+ /// .with_error(DataFusionError::Internal("foo".to_owned()));
709+ /// assert_contains!(builder.error_or(42).unwrap_err().to_string(), "Internal error: foo");
710+ /// ```
711+ pub fn with_error ( mut self , error : DataFusionError ) -> Self {
712+ self . 0 . push ( error) ;
713+ self
714+ }
715+
716+ /// Returns `Ok(ok)` if no errors were added to the builder,
717+ /// otherwise returns a `Result::Err`
662718 pub fn error_or < T > ( self , ok : T ) -> Result < T , DataFusionError > {
663719 match self . 0 . len ( ) {
664720 0 => Ok ( ok) ,
@@ -668,12 +724,6 @@ impl DataFusionErrorBuilder {
668724 }
669725}
670726
671- impl Default for DataFusionErrorBuilder {
672- fn default ( ) -> Self {
673- Self :: new ( )
674- }
675- }
676-
677727/// Unwrap an `Option` if possible. Otherwise return an `DataFusionError::Internal`.
678728/// In normal usage of DataFusion the unwrap should always succeed.
679729///
0 commit comments