Get deepest underlying [`DataFusionError`] [`DataFusionError`]s sometimes form a chain, such as `DataFusionError::ArrowError()` in order to conform to the correct error signature. Thus sometimes there is a chain several layers deep that can obscure the original error. This function finds the lowest level DataFusionError possible. For example, `find_root` will return`DataFusionError::ResourceExh
(&self)
| 434 | /// |
| 435 | /// This may be the same as `self`. |
| 436 | pub fn find_root(&self) -> &Self { |
| 437 | // Note: This is a non-recursive algorithm so we do not run |
| 438 | // out of stack space, even for long error chains. |
| 439 | |
| 440 | let mut last_datafusion_error = self; |
| 441 | let mut root_error: &dyn Error = self; |
| 442 | while let Some(source) = root_error.source() { |
| 443 | // walk the next level |
| 444 | root_error = source; |
| 445 | // remember the lowest datafusion error so far |
| 446 | if let Some(e) = root_error.downcast_ref::<DataFusionError>() { |
| 447 | last_datafusion_error = e; |
| 448 | } else if let Some(e) = root_error.downcast_ref::<Arc<DataFusionError>>() { |
| 449 | // As `Arc<T>::source()` calls through to `T::source()` we need to |
| 450 | // explicitly match `Arc<DataFusionError>` to capture it |
| 451 | last_datafusion_error = e.as_ref(); |
| 452 | } |
| 453 | } |
| 454 | // return last checkpoint (which may be the original error) |
| 455 | last_datafusion_error |
| 456 | } |
| 457 | |
| 458 | /// wraps self in Self::Context with a description |
| 459 | pub fn context(self, description: impl Into<String>) -> Self { |