NHacker Next
  • new
  • past
  • show
  • ask
  • show
  • jobs
  • submit
Designing Error Types in Rust Libraries (d34dl0ck.me)
saghm 3 days ago [-]
In addition to the tradeoffs the article discusses, one other potential use for using traits rather than concrete error types is that you could also choose to use a different container than `Box` if you need different properties. As an example, one library I worked on needed to track errors that might occur in background threads and sometimes return them (or merge the info in them with other errors) to users when an operation failed later. Because the client the library provided could itself be used concurrently, this meant that we sometimes had to return the same error (or at least, parts of the same information from the error) in multiple different threads, and not all of the error types we wrapped were possible to Clone. Wrapping these errors internally in an `Arc` made it possible for us to clone our top-level error type and greatly simplify our internal logic handling these cases. I imagine that this isn't a particularly common problem people well run into, but at the very least being able to wrap `dyn Error + Send + Sync` is a nice example of how composable a lot of the concepts in how to design an API in Rust are.
vlovich123 3 days ago [-]
This post overlooks a very important technique to get type hiding without the cost of boxing. Having an opaque public type that wraps the private one:

    public struct SqlError(sqlx::Error)

    #[derive(Debug, thiserror::Error)]
    pub enum MyError {
        #[error("Database error: {0}")]
        DatabaseError(#[from] SqlError)
    }
It’s a bit more annoying to construct since result has to have a .map_error(SqlError) but that’s not that much honestly.
saghm 3 days ago [-]
This also gives the flexibility to easily change your decision later if you determine that it's important to expose the inner type for some reason. With a boxed trait error type, you'd only be able to by adding a new method to one of the traits, and the implementation would be a lot messier with downcasting, (and unwrapping if you wanted to avoid the optional, which could open the door to bugs where you accidentally don't have the error type you expect and then panic).
5422m4n 3 days ago [-]
That's a valid point, it never occurred to me that this pattern remains useful. But I certainly see the charm it has besides being a bit more annoying to handwrite. I will update the post. Thanks
Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact
Rendered at 10:59:07 GMT+0000 (Coordinated Universal Time) with Vercel.