Error handling 创建新错误时重用现有错误的描述

Error handling 创建新错误时重用现有错误的描述,error-handling,rust,Error Handling,Rust,我在Rust中有以下代码,它不编译,但显示了我想做的事情的意图 pub fn parse(cursor: &mut io::Cursor<&[u8]>) -> io::Result<Ack> { use self::byteorder::{BigEndian, ReadBytesExt}; use self::core::error::Error; match cursor.read_u16:

我在Rust中有以下代码,它不编译,但显示了我想做的事情的意图

    pub fn parse(cursor: &mut io::Cursor<&[u8]>) -> io::Result<Ack> {
        use self::byteorder::{BigEndian, ReadBytesExt};
        use self::core::error::Error;

        match cursor.read_u16::<BigEndian>() {
            Err(byteorder::Error::Io(error)) => Err(error),
            Err(error) =>
                Err(io::Error::new(io::ErrorKind::Other, error.description(),
                                   None)),
            Ok(value) => Ok(Ack { block_number: value })
        }
    }
发布fn解析(游标:&mut io::游标)->io::结果{ 使用self::byteorder::{BigEndian,ReadBytesExt}; 使用self::core::error::error; 匹配光标。读取\ u16::(){ Err(字节顺序::错误::Io(错误))=>Err(错误), Err(error)=> Err(io::Error::new(io::ErrorKind::Other,Error.description(), 无),, Ok(值)=>Ok(确认{块编号:值}) } } 本质上,我希望获取字节顺序库返回的错误的错误描述,并使用它创建一个错误的描述,我将传递回我的库的用户。这在
数据包中失败。rs:166:58:166:63错误:
错误
寿命不够长,我理解原因

字节顺序库通过在
byteorder::Error::io
构造函数中包装
std::io::Result
来解决此问题。但是,我不想采用这种方法,因为我必须定义自己的错误类型,该类型包含
std::io::error
byteorder::error
。在我看来,我的用户不应该知道或关心我使用字节顺序库,它也不应该是我界面的一部分


我是个新手,还不知道语言和设计的习惯用法和最佳实践。处理这个问题我有什么选择?

我无法测试您的代码,所以我不能确定。ref关键字还不够吗

Err(byteorder::Error::Io(ref error)) => Err(error),

您的问题实际上在于,第二个参数是
&'static str
,而返回一个
&'a str
,其中
'a
是错误对象本身的生存期,它小于
'static
。因此,您不能将其用于
io::Error
的描述

最简单的修复方法是将
byteorder::Error
描述移动到
io::Error
detail
字段:

Err(error) =>
    Err(io::Error::new(
        io::ErrorKind::Other,
        "byteorder error",
        Some(error.description().to_string())
    )),

不过,您应该认真考虑编写一个封装所有“下游”错误的自定义包装错误类型。使用正确编写的实例,您应该能够编写如下内容

try!(cursor.read_u16::<BigEndian>()
    .map(|value| Ack { block_number: value }))
试试看!(光标。读_u16::)
.map(| value | Ack{block_number:value}))

而不是你的整个比赛。自定义错误包装器也将在您的程序增长和出现更多“下游”错误源时为您提供帮助-您可以添加新的枚举变量和/或
FromError
实现以支持这些新错误。

不幸的是,我要到明天才能再次回到这一点,但我将尝试并报告。谢谢。我最终实现了自定义错误包装器,因为这似乎是最惯用的方法。我还没试过,但是试一下吧!。。。地图方法很简洁。