error-handling - Rust Snafu缺少 'source'字段

标签 error-handling rust

我正在尝试使用snafu crate 进行错误处理,但不断出现错误,我的Error枚举结构缺少'source'并且IntoError没有隐含Error:

//main.rs
use snafu::{ResultExt, Snafu};
#[derive(Debug, Snafu)]
#[snafu(visibility = "pub(crate)")]
pub enum Error{
    #[snafu(display("Could not load gallery JSON: {}: {}", json_path, source))]
    LoadGallery {
        source: std::io::Error,
        json_path: String,
    },
}
//gallery.rs
use snafu::{ResultExt}; 
use crate::Error::{LoadGallery};

pub struct Gallery{
    name: String,
}

impl Gallery{
    pub fn from_json(json_path: String)->Result<()>{
        let configuration = std::fs::read_to_string(&json_path).context(LoadGallery { json_path })?;
        Ok(())
    }
}
结果是:
let configuration = std::fs::read_to_string(&json_path).context(LoadGallery { json_path })?;
|                                                                         ^^^^^^^^^^^ missing `source`
let configuration = std::fs::read_to_string(&json_path).context(LoadGallery { json_path })?;
|                                                                         ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `IntoError<_>` is not implemented for `Error`
根据文档中的示例,我看不到我做错了什么:
use snafu::{ResultExt, Snafu};
use std::{fs, io, path::PathBuf};

#[derive(Debug, Snafu)]
enum Error {
    #[snafu(display("Unable to read configuration from {}: {}", path.display(), source))]
    ReadConfiguration { source: io::Error, path: PathBuf },

    #[snafu(display("Unable to write result to {}: {}", path.display(), source))]
    WriteResult { source: io::Error, path: PathBuf },
}

type Result<T, E = Error> = std::result::Result<T, E>;

fn process_data() -> Result<()> {
    let path = "config.toml";
    let configuration = fs::read_to_string(path).context(ReadConfiguration { path })?;
    let path = unpack_config(&configuration);
    fs::write(&path, b"My complex calculation").context(WriteResult { path })?;
    Ok(())
}

fn unpack_config(data: &str) -> &str {
    "/some/path/that/does/not/exist"
}

最佳答案

这是因为在构造LoadGallery时,您正在尝试构造Error::LoadGallery。然后,您会收到一个编译错误,提示“缺少source”,因为Error::LoadGallery变体具有source字段。解决这个问题很简单,您只需要更改导入的LoadGallery

// Not this one:
// use crate::Error::LoadGallery;

// This one:
use crate::LoadGallery;
为什么?因为 snafu struct的每个变体生成一个Error。因此,正在生成一个struct LoadGallery。该结构不包含source字段,这就是为什么您可以在不使用source的情况下构造它并将其传递给 context() 的原因,因为它实际上不是Error::LoadGallery
您的from_json()还需要返回Result<(), Error>而不是Result<()>(您没有类型别名,如示例中所示)。
use crate::{Error, LoadGallery};
use snafu::ResultExt;

pub struct Gallery {
    name: String,
}

impl Gallery {
    pub fn from_json(json_path: String) -> Result<(), Error> {
        let configuration =
            std::fs::read_to_string(&json_path).context(LoadGallery { json_path })?;
        Ok(())
    }
}
如果您感到好奇,可以使用 cargo expand 检查宏扩展到的内容。您首先需要通过执行cargo install expand进行安装。然后,您可以在任何项目中执行 cargo expand

关于error-handling - Rust Snafu缺少 'source'字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66510122/

相关文章:

rust - 如何在 Fn 特征绑定(bind)返回引用上定义生命周期?

r - 为什么抑制Rmarkdown中的错误不起作用?

vba - 通过Excel VBA作为电子邮件附件发送的文件始终损坏

knockout.js - John Papa 的 HotTowel this.handleError 未定义...为什么?

for-loop - 在其 for 循环中访问迭代器

rust - 预期类型参数,发现不透明类型

rust - 有没有办法限制 Rust 中调试输出的向量/字符串长度?

string - Rust 是否提供了一种直接从字节 (u8) 数组中的 ASCII 数据解析整数的方法?

python - 如何获得成功和错误代码?

node.js - 如何在 Node js 中不使用 try catch 子句避免内部服务器错误?