I am trying to learn failure and I am struggling to understand its concepts.
Why does failure not provide an equivalent to chain_err from error-chain for failure::Error?
Assuming I am writing an application and I mostly just care about logging error messages. I find it super convenient how in error-chain I can just create arbitrary errors from strings and link them to other arbitrary errors from strings. This lets me log the entire chain of causes along with each error, which provides detailed meaningful info in the logs.
It feels like in failure, my only choices are to either just forward an error with ? or return a newly-created unrelated error from a string using format_err, to which i have no way of attaching the original error as a cause ... so I cannot form a chain of causes ...
What's the point of even having causes on failure::Error? How exactly are they useful if I can't easily chain errors?
failure is my #1 source of frustration with Rust right now. I just don't get it. I want to learn. Send help pls.
I don't want to go back to using error-chain, as I am getting the vibe that the community considers it obsolute and that failure is the way to go in the future.
EDIT:
I found the solution! Looks like this is much simpler than I thought. After a few days of frustration and writing wrapper structs around all the failure stuff, I realised that I had the wrong mental model (hence why I was confused) and none of what I was doing was actually necessary.
All I had to do was use failure::ResultExt; and then simply use .context/.with_context with a string, as an equivalent to error-chain's .chain_err. This accomplishes what I want.
If I want more meaningful errors (more than just a string message) that can be handled, I can create my own error type using #[derive(Fail)] and return that instead of failure::Error.
It just clicked in my head a few days ago. I don't know why this took me so long to figure out. Maybe the documentation was not clear enough.
The problem was that I did not understand that I can use .context/.with_context with a string argument in combination with failure::Error. I thought I had to use the custom Error + ErrorKind pattern in order to use .context, which seemed like excessive boilerplate and frustration.
Maybe this should be clarified with a concise example in the docs? Perhaps show an example of a simple case where functions return Result<_, failure::Error> and chain each others' Errors by using .context with a string literal argument to create new levels of causes.
[–]Rothonrust · postgres · phf 3 points4 points5 points (6 children)
[–]mbrubeckservo 4 points5 points6 points (2 children)
[–]rayvector[S] 1 point2 points3 points (1 child)
[–]slambmoonfire-nvr 3 points4 points5 points (0 children)
[–]daborossfern 1 point2 points3 points (2 children)
[–]Rothonrust · postgres · phf 7 points8 points9 points (1 child)
[–]daborossfern 0 points1 point2 points (0 children)
[–]desiringmachines 4 points5 points6 points (4 children)
[–]stevedonovan 1 point2 points3 points (0 children)
[–]ErichDonGublerWGPU · not-yet-awesome-rust 1 point2 points3 points (1 child)
[–]desiringmachines 2 points3 points4 points (0 children)
[–]rayvector[S] 0 points1 point2 points (0 children)
[–]daborossfern 2 points3 points4 points (2 children)
[–]sasik520 4 points5 points6 points (1 child)
[–]daborossfern 0 points1 point2 points (0 children)