What is the right way to handle errors from different sources?

I have a library that needs to handle several different types of errors: OS errors, errors generated in the library, Tokio errors and error codes returned from a remote service it connects to.

What's the idiomatic way to handle those in code? Are there any tutorials?

Define your own error type, and make sure it's possible for downstream users to extract the underlying errors (if that makes sense).

For conveniently making your own error type, you can also use an external crate, such as thiserror.

An example of what @H2CO3 is describing.

All the hand-written From instances let ? be used on functional calls that produce the underlying error. They're automagically promoted to your error type.