Cheappie commented on issue #3285:
URL: https://github.com/apache/arrow-rs/issues/3285#issuecomment-1344100205
I have seen that `anyhow` crate is being considered. In past I have been
exploring if there is any easy way to recover type information without
downcasting in caller and actually it is possible by preserving root type id.
But I am not sure if there are any corner case around that solution, so please
treat it as fun fact.
```
use anyhow::anyhow;
use std::any::TypeId;
use std::fmt::{Debug, Display, Formatter};
use std::io::ErrorKind::{NotFound, UnexpectedEof};
use std::marker::PhantomData;
use thiserror::__private::AsDynError;
pub struct ParquetError {
root_type_id: TypeId,
error: anyhow::Error,
}
impl ParquetError {
pub fn context<C: Display + Send + Sync + 'static>(self, context: C) ->
ParquetError {
let err_with_ctx = self.error.context(context);
ParquetError {
root_type_id: self.root_type_id,
error: err_with_ctx,
}
}
}
impl Display for ParquetError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
Display::fmt(&self.error, f)
}
}
impl Debug for ParquetError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
Debug::fmt(&self.error, f)
}
}
impl std::error::Error for ParquetError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
Some(self.error.as_dyn_error())
}
}
///
/// Known errors
///
pub enum Error<'a> {
IO(&'a std::io::Error),
Other(&'a dyn std::error::Error),
}
impl ParquetError {
pub fn root_cause(&self) -> Error<'_> {
let root = self.error.root_cause();
if self.root_type_id == TypeId::of::<std::io::Error>() {
Error::IO(root.downcast_ref::<std::io::Error>().expect("infallible"))
} else {
Error::Other(root)
}
}
}
macro_rules! parquet_err {
($err:expr) => {{
let root_type_id = capture_type_id(&$err);
let error = anyhow!($err);
ParquetError {
root_type_id,
error,
}
}};
}
fn capture_type_id<E: 'static>(_: &E) -> TypeId {
TypeId::of::<E>()
}
#[test]
fn test() {
let err = parquet_err!(std::io::Error::new(NotFound, "Not found"));
// easy way to access known errors, without need to repeat downcast_ref
// match err.root_cause() {
// Error::IO(io) => {
// println!("Some io error; {:?}", io);
// }
// Error::Other(other) => {
// println!("Other error; {:?}", other);
// }
// }
println!(
"{:?}",
err.context("When looking for")
.context("Something important")
.context("Unable to locate parquet metadata")
);
}
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]