The anyhow crate complements thiserror pretty well in my experience. I use it "top-down" facing where individual errors in any component are defined with thiserror, but then we bubble them up by wrapping them in a `anyhow::Error` if we don't know what to do with them. It also has the nice thing of being able to produce simplified stack traces to help diagnose where things are going wrong. And then you can downcast to component-level thiserror Errors if you want to inspect something closely from high up.