The work function knows nothing about the job number it is working on, but could fail with various errors (std::num::ParseIntError, std::io::Error, etc, all error_chain foreign_links).
However I'm not sure why you would want that. The default error order that chain_err gives you is more correct: the cause of a job failure is that work() has failed, not the other way around.
The reason I need to prepend is that each work() occurs in a thread (using rayon) so I want to construct error messages in the main thread of the form "Job number: error message".
I tried your suggestion & many variations but couldn't figure it out.
The closest I've got is this:
// inside error_chain!
errors { Fail(u: u32, err: String) { display("[{: >5}] {}", u, err) } }
// elsewhere
pub fn get_error(err: Error) -> String {
let mut error = format!("ERROR: {}", err);
for err in err.iter().skip(1) {
error.push_str(&format!(": {}", err));
}
error
}
// at the point of use:
let reply = work(&data)
.map_err(|err| Err(ErrorKind::Fail(u, get_error(err))))?;
This fails to compile with:
error[E0277]: the trait bound `errors::Error: std::convert::From<std::result::Result<_, errors::ErrorKind>>` is not satisfied
--> src/plan/process.rs:62:25
|
62 | let reply = work(&data)
| __________________^
63 | | .map_err(|err| Err(ErrorKind::Fail(u, get_error(err))))?;
| |____________________________________________________________________^ the trait `std::convert::From<std::result::Result<_, errors::ErrorKind>>` is not implemented for `errors::Error`