Configuration parsing issues

I have a function that can parse yml and map it to the corresponding structure. It is OK through unit testing, but when I use it in main, there will be exceptions that cannot be resolved

use std::fs::File;

pub fn load_config<T>(path: &str) -> Option<T>
where T:serde::de::DeserializeOwned
{
    let file:File = match std::fs::File::open(path) {
        Ok(f) => {f},
        Err(_) => {panic!("not found file")},
    };
     match serde_yaml::from_reader::<File,T>(file) {
        Ok(data) => {
            return Some(data)
        },
        Err(_) => {
            panic!("load fail")  //there error
        },
    }
}
#[cfg(test)]
mod tests {
    use serde::Deserialize;

    use super::*;

    #[derive(Deserialize,Debug)]
    struct Demo{
        a:String,
        b:u8,
    }

    #[test]
    pub fn load_config_test() {
        match load_config::<Demo>("demo.yml") {
            None => {
                println!("None");
            }
            Some(config) => {
                println!("{:#?}", config);
            }
        }
    }
}

error log:

thread 'main' panicked at 'load fail', D:\project\spider\spider-conf-parser\src/lib.rs:25:13
stack backtrace:
0: std::panicking::begin_panic_handler
at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library\std\src\panicking.rs:593
1: core::panicking::panic_fmt
at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library\core\src\panicking.rs:67
2: spider_yml_parser::load_config<spider_yml_parser::Env>
at .\spider-conf-parser\src\lib.rs:25
3: spider_registry::main::async_block$0
at .\spider-registry\src\main.rs:18
4: tokio::runtime::park::impl$4::block_on::closure$0<enum2$<spider_registry::main::async_block_env$0> >
at C:\Users\Administrator.cargo\registry\src\index.crates.io-6f17d22bba15001f\tokio-1.32.0\src\runtime\park.rs:282
5: tokio::runtime::coop::with_budget
at C:\Users\Administrator.cargo\registry\src\index.crates.io-6f17d22bba15001f\tokio-1.32.0\src\runtime\coop.rs:107
6: tokio::runtime::coop::budget
at C:\Users\Administrator.cargo\registry\src\index.crates.io-6f17d22bba15001f\tokio-1.32.0\src\runtime\coop.rs:73
7: tokio::runtime::park::CachedParkThread::block_on<enum2$<spider_registry::main::async_block_env$0> >
at C:\Users\Administrator.cargo\registry\src\index.crates.io-6f17d22bba15001f\tokio-1.32.0\src\runtime\park.rs:282
8: tokio::runtime::context::blocking::BlockingRegionGuard::block_on<enum2$<spider_registry::main::async_block_env$0> >
at C:\Users\Administrator.cargo\registry\src\index.crates.io-6f17d22bba15001f\tokio-1.32.0\src\runtime\context\blocking.rs:66
9: tokio::runtime::scheduler::multi_thread::impl$0::block_on::closure$0<enum2$<spider_registry::main::async_block_env$0> >
at C:\Users\Administrator.cargo\registry\src\index.crates.io-6f17d22bba15001f\tokio-1.32.0\src\runtime\scheduler\multi_thread\mod.rs:87
10: tokio::runtime::context::runtime::enter_runtime<tokio::runtime::scheduler::multi_thread::impl$0::block_on::closure_env$0<enum2$<spider_registry::main::async_block_env$0> >,enum2$<core::result::Result<tuple$<>,std::io::error::Error> > >
at C:\Users\Administrator.cargo\registry\src\index.crates.io-6f17d22bba15001f\tokio-1.32.0\src\runtime\context\runtime.rs:65
11: tokio::runtime::scheduler::multi_thread::MultiThread::block_on<enum2$<spider_registry::main::async_block_env$0> >
at C:\Users\Administrator.cargo\registry\src\index.crates.io-6f17d22bba15001f\tokio-1.32.0\src\runtime\scheduler\multi_thread\mod.rs:86
12: tokio::runtime::runtime::Runtime::block_on<enum2$<spider_registry::main::async_block_env$0> >
at C:\Users\Administrator.cargo\registry\src\index.crates.io-6f17d22bba15001f\tokio-1.32.0\src\runtime\runtime.rs:349
13: spider_registry::main
at .\spider-registry\src\main.rs:32
14: core::ops::function::FnOnce::call_once<enum2$<core::result::Result<tuple$<>,std::io::error::Error> > (*)(),tuple$<> >
at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be\library\core\src\ops\function.rs:250
note: Some details are omitted, run with RUST_BACKTRACE=full for a verbose backtrace.
error: process didn't exit successfully: target\debug\spider-registry.exe (exit code: 101)

Without knowing the exact error, and/or the contents of the file being parsed and the exact structure into which it is being parsed, it's impossible to tell what the problem is and how to fix it.

Sometimes a useful idea is to construct the config in Rust, then use serde_yaml to write it to a file. Comparing that with your own config file might give a clue to what the problem is.

1 Like

I have re edited the wrong log

Unfortunately, the stack trace alone is not useful – you have already marked where the error happens in the code.

Please post the contents of the config YAML file and the full definition of every type (structs and enums), transitively, that you are trying to parse it into.

To expand what Alice means, you can do this as I suggest here:

fn check<T>(v: T)
where
    T: Serialize + DeserializeOwned + PartialEq + Debug,
{
    let s = serde_yaml::to_string(&v).unwrap();
    println!("{v:?} =>\n{s}");
    let parsed: T = serde_yaml::from_str(&s).unwrap();
    assert_eq!(v, parsed);
}

Rust Playground

By doing Err(_) and panic!("load fail") you ignore the error message which would otherwise tell you what is wrong with your config file and just say "something went wrong".

I'd modify the code to at least do this:

Err(e) => {
  panic!("Load fail: {e}");
}

That will print the error message and tell you why your configuration parsing is failing. I'd also do the same for when the file doesn't load.

3 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.