Rust Error Handling - Best Practices

Ғылым және технология

Here are some best practices for error handling in Rust programming that I've found effective:
- For tests and examples, use "box dyn error" instead of "anyhow."
- Prefer the "?" pattern over "unwrap" or "expect," even in tests and examples, to align with production coding standards.
- "Box dyn error" is excellent for error passthrough, as are `map_err` and `ok_or` with static strings and formatted strings.
- In production code, use an enum with fully descriptive variant names and favor struct variants with clear names over tuple variants.
- Avoid relying on the display to convey the meaning of error variants.
- In web or device applications, human error rendering might not occur at the enum/type level, so using Debug for display may suffice.
- For web or device applications, using Serialize for errors that need to be logged or sent to the client for display can be a powerful and straightforward pattern.
- Prioritize clarity in error naming (variants) and focus on consistency as the code develops.
- Don't be afraid of medium-length enum variant names; remember, type refactoring is straightforward.
- In summary, start with progressive and clear practices, and become more structured as the code matures.
== Jeremy Chone:
- Patreon - / jeremychone - Any help is a big help (for Rust educational content)
- Twitter - / jeremychone
- Discord general-rust - / discord
- Discord rust10x - / discord
- Rust10x - rust10x.com - Rust resources for production coding.
Big thanks to CrabNebula (crabnebula.dev/) for sponsoring this channel.
== Rust10x AI / OpenAI / Ollama
- Rust OpenAI API Tutorial: • Learn Rust OpenAI API ...
- Rust Ollama Tutorial: • Rust Ollama By Example...
== Rust10x Web App production coding:
Episode 01: • Rust Axum Production C...
Episode 02: • Rust Sea-Query + SQLX ...
Episode 03: • Rust Workspace Product...
Episode 04: • Rust Argon 2 Password ...
Episode 05.1: • Rust RPC Router - Axum...
Web Site: rust10x.com/web-app
GitHub: github.com/rust10x/rust-web-app
Discord rust10x - / discord
Patreon - / jeremychone - Any help is a big help (for Rust Production Coding educational content)
== Other
Other popular Rust Programming videos:
- Rust Web App Production Coding Blueprint - • Rust Axum Production C...
- Rust Axum - Full Course - • Rust Axum Full Course ...
- Rust Type State Builder Pattern - • Rust Programming: Type...
- Quick Start Code Layout - • Rust - Simple Code Lay...
- AWESOME-APP Full Overview - Rust template for building Awesome Desktop Application: • Building Awesome Deskt...
- Tauri Quick Introduction (Desktop App wit Rust Programming): • Rust Tauri 1.0 - Quick...
- Rust Web App tutorials series: • Rust Web App - 1/3 - D...
- Rust Bevy Full Tutorial - Game Development with Rust: • Rust Bevy Full Tutoria...
- Rust for Java Developers series: • Rust for Java Develope...
Playlists:
- Rust AI Programming Series: • Rust AI Programming Se...
- Rust Web App Production Coding Series: • Rust Production Coding...
- Rust For Desktop App: • Rust Programming for D...
- Everything Rust Programming - Tutorials, Courses, Tips, Examples: • Everything Rust Progra...
- Rust Programming for Web Development: • Rust Programming for W...
- Rust Courses: • Rust Course 2021 by th...
- Rust for Java Developers: • Rust for Java Developers
Rust10x - Coding Resources for Production Coding in Rust. ➜ rust10x.com
Other notes:
- ScreenBrush for the green lines. (Gromit seems to be the equivalent on Linux)
- Sketchapp for some graphics.
- Davinci Resolve and Fusion video editing.
- VSCode with Google Material icon themes (with some customization)

Пікірлер: 59

  • @yudhiesh1997
    @yudhiesh1997Ай бұрын

    More videos on best practices in Rust please! Perhaps some on Tests, Tracing, Scaling Rust Backends, etc.

  • @Aucacoyan
    @AucacoyanАй бұрын

    Best Practices? yes please!

  • @dannelalbert7111
    @dannelalbert7111Ай бұрын

    This is by far the best explanation of how to do robust error handling in Rust. I've always been a bit lost without anyhow and thiserr. This seems like a fantastic workflow that checks all the boxes I have been looking for progressing from test to production code without getting bogged down. Thank you for sharing this!

  • @yelan5034
    @yelan50343 күн бұрын

    Awesome, I was struggling with how to handle error gracefully, and you help me out a lot

  • @jamesray1820
    @jamesray1820Ай бұрын

    Great, video I have been using these patterns in part since I started watching your videos. It is great to have it completely explained. Thank you!

  • @SniffleSneeze
    @SniffleSneezeАй бұрын

    this is amazing ! thanks so much for taking the time to release such a good quality content.

  • @gabrielkwong1878
    @gabrielkwong1878Ай бұрын

    Amazing video! More best practices videos please and thank you very much!

  • @norminemralino2260
    @norminemralino2260Ай бұрын

    Another great video. I’ve noticed Jeremy talking about error handling in his last few videos, so it’s nice to see him do a video on error handling specifically. Though I think it could use a part 2. Maybe go ahead and implement structured Error type and add an example of a custom display for it and an example of calling the error. Maybe also add a error from a different module (he kinda talked about it)

  • @maxali6591
    @maxali6591Ай бұрын

    Cool I was looking a video in that way. Thank you!

  • @jensen7141
    @jensen7141Ай бұрын

    High quality content! Thank you

  • @dkoleary88
    @dkoleary888 күн бұрын

    This is awesome. Thanks for making these videos. Very clear, concise and easy to understand and the actual content is amazing.

  • @JeremyChone

    @JeremyChone

    8 күн бұрын

    Thanks for the feedback.

  • @TheOmfg02
    @TheOmfg02Ай бұрын

    Great video!

  • @TheZdannar
    @TheZdannarАй бұрын

    Great video. Nice pattern.

  • @guacharo.w3871
    @guacharo.w3871Ай бұрын

    thiserror crate is very usable for a prod too Btw great video!

  • @JeremyChone

    @JeremyChone

    Ай бұрын

    Yes, if your product requires "English" display for your errors, this error is okay. However, I think that "English" display is useful only if it is intended to be shown to the end user. If it is just for developers and IT people, then the debug serialization as display is sufficient in most cases. This is why I like derive_more. It's relatively equivalent in result but we can choose what we want.

  • @irlshrek
    @irlshrekАй бұрын

    love this!!

  • @pkozelka
    @pkozelkaАй бұрын

    very nice, will try

  • @arcaneminded
    @arcanemindedАй бұрын

    Thanks mate. Small nit-pick you mentioned using embedded 'one day', but if you're using embedded, I'd really try to stay away from using trait objects and use the anyhow crate. Also the pass through `?` get's a little more complicated when dealing with embedded.

  • @JeremyChone

    @JeremyChone

    Ай бұрын

    Ho, good points. I can understand the confusion. I meant just the type alias of Result, not the Box part for the error. Also, the whole ? and error handling seems to be a different beast in embedded, so the comment was a little misleading, I agree. I should have removed this comment, and just said, "same as std, and I like using core when possible as it lets me know what is not dependent on std."

  • @cariyaputta
    @cariyaputtaАй бұрын

    Thanks.

  • @juliuso.1183
    @juliuso.118327 күн бұрын

    Hey Jeremy Thanks for the great series! I am learning a lot that I am trying to incorporate into our production server designs.. Is there a reason as to why you use `impl std::fmt::Display` instead of `impl ToString` for custom error messages?

  • @JeremyChone

    @JeremyChone

    27 күн бұрын

    We could use `impl ToString`, but it is a little less flexible and less common/idiomatic than `impl Display`. For example, with `impl ToString` for `format!`/`println!`, we have to call `to_string()`, which requires adding them as an "argument," whereas with `impl Display`, we can just inline them in `{...}`. Also, typically, if we want a type to have `to_string()`/`ToString`, we would `impl Display for MyType` rather than implementing `ToString`. There's a blanket implementation of `ToString` for all types that implement `Display`, so we're good. Now, the other option that might be used is `impl Into`, which is more suitable for cases where the function needs to own the `String` but wants to give the caller the option to pass an owned `String` to avoid a new allocation if possible. If the caller passes a reference to a `String` or `str`, `into()` will allocate a new `String`.

  • @Boronesss
    @BoronesssАй бұрын

    happy coding!

  • @froop2393
    @froop2393Ай бұрын

    great! I like it. I have one question: You mentioned not to use an error module. But then you created one and did a (reexport?) to get rid of the error::Error import. Is that what you suggest as best practise?

  • @JeremyChone

    @JeremyChone

    Ай бұрын

    Good point. I noticed after rewatching the video that this could be misleading. What I meant was that I do not expose my module Error within a submodule "error". However, for code organization, I put the code in error.rs and then re-export it at the root of the module. I should have clarified that. I showed it, but did not clarify it.

  • @betterinbooks
    @betterinbooksАй бұрын

    thank you

  • @LucasOe
    @LucasOeАй бұрын

    For one off errors, do you create a new error variant, or do you just use a generic msg error with a string?

  • @JeremyChone

    @JeremyChone

    Ай бұрын

    Depends if I am early in my code. If I am, then I use the Custom variant and the from static str, or formatted string. Then, when the code matures, I remove the Custom and all become variants, each with a descriptive variant name. I first focus on being descriptive in my variant names, and then work on consistency as the code design matures. Variant naming refactoring are simple and fast.

  • @floristrading8418
    @floristrading8418Ай бұрын

    had my suvbscribe after 1:25

  • @Jubijub
    @JubijubАй бұрын

    Thank you so much for this video, this is so useful. Beginner content is nice, but the examples are too trivial, and in particular don't cover well how to organize the code. Those are really neat patterns to know. More content like this please !

  • @JeremyChone

    @JeremyChone

    Ай бұрын

    Thanks. You can find some examples of this usage in other videos/codebases. For instance: AI Function Calling: kzread.info/dash/bejne/ZIFksrWimq_UmdY.html Rust AI Buddy: kzread.info/dash/bejne/gnyWpc-Ck868YpM.html And the big Rust-Web-App blueprint github.com/rust10x/rust-web-app

  • @adamsmith7630
    @adamsmith7630Ай бұрын

    I don't think I understand why one might prefer writing your own boilerplate for your Error enum rather than using thiserror. Is it just to have finer control of the Display implementation?

  • @JeremyChone

    @JeremyChone

    Ай бұрын

    Yes, thiserror takes over the display, which in my approach I don’t typically need as Debug as Display is plenty enough. With derive_more, I can still remove the From and Dispatch boilerplate, but I have the choice. About the display annotation: Annotating each variant with display is redundant and can lead to the anti-pattern of capturing meaning as text rather than having fully descriptive variant names and structures. For simple command-line applications, it’s fine, and the derive_more display removes the boilerplate like this error. For web or even desktop apps, typically we want to move the structure of the error to another system (e.g., log service/system) and have it displayed to the end user. For this, serializing to JSON is often a great approach.

  • @NOISCALE
    @NOISCALEАй бұрын

    ❤❤❤

  • @sunofabeach9424
    @sunofabeach9424Ай бұрын

    how do you briefly display types on 10:39?

  • @JeremyChone

    @JeremyChone

    Ай бұрын

    I use Toggle VSCode extension, and then add a key binding to toggle the inlay. You can find more info there: rust10x.com/vscode#keybinding-for-toggling-the-inlays (Note: this does not require the Rust10x vscode extension)

  • @sunofabeach9424

    @sunofabeach9424

    Ай бұрын

    @@JeremyChone thnaks

  • @addDexter
    @addDexterАй бұрын

    Jeremy Chone have spoken, Lissan al Caib !

  • @user-of6ls2ng5l
    @user-of6ls2ng5lАй бұрын

    Why didn't you show error creation for fs. What will you call the enum ? ErrorFs ?

  • @JeremyChone

    @JeremyChone

    Ай бұрын

    Ah, it depends. I do not include error types for all submodules, focusing more on the main submodules that are likely need to have their own Error. This was just an example, but if I decided to have `crate::fs_utils` (I would rename it to avoid confusion with `std::fs`), I would do something like: `src/fs_utils/error.rs` to define `Error` with the `Result` type alias. And in `src/fs_utils/mod.rs` I would do: ```rust mod error; pub use self::error::{Error, Result}; ``` This way, if I am outside of the `fs_utils` module, I would use `Result` or `Error` as `fs_utils::Result` or `fs_utils::Error::...`. If I am within the `fs_utils` module, I would import and use `Result` or `Error` as needed.

  • @user-of6ls2ng5l

    @user-of6ls2ng5l

    Ай бұрын

    @JeremyChone thanks so much for the detailed reply)

  • @user-of6ls2ng5l

    @user-of6ls2ng5l

    Ай бұрын

    @JeremyChone please record a video: best practices for structuring a project on Rust. It's very hard to decide what names to give folders/modules for certain features. Thanks.

  • @JeremyChone

    @JeremyChone

    Ай бұрын

    @@user-of6ls2ng5l Yes, there isn't a hard rule about when it's a good time to create an error for a module. However, there are some rules of thumb, so I need to articulate those. Also, these rules are okay to be broken once in a while. Additionally, some can be considered personal preferences. One video I want to make is "Module Best Practices," and in this video, we can definitely tackle this subject.

  • @MrHirenP
    @MrHirenPАй бұрын

    Hi! Is #[derive(From)] external crate proc macro? Or something to enable in std library?

  • @MrHirenP

    @MrHirenP

    Ай бұрын

    Ok it’s from derive_more. Thanks!

  • @JeremyChone

    @JeremyChone

    Ай бұрын

    Yes, as @MrHirenP said, it's part of the derive_more crate, which offers some useful procedural macros. I like it because it provides the trivial impl From (similar to the thiserror transparent), but separates it from the Display implementations (which thiserror takes over).

  • @rougegorge3192
    @rougegorge319215 күн бұрын

    Fait tes tutos en francais la vague rust arrive dans le main stream

  • @JeremyChone

    @JeremyChone

    15 күн бұрын

    Thanks, could be a good idea. But this would probably need to be in another channel now and quite a bit of work to do both.

  • @CuriousSpy
    @CuriousSpyАй бұрын

    Error::LimitTooHigh(LimitDescription)

  • @JeremyChone

    @JeremyChone

    Ай бұрын

    I would use that pattern only if LimitDescription is used in other variants. Otherwise, I inline the struct members as variant struct members. It avoids unnecessary type proliferation. However, this could be considered a personal preference. Both are valid approaches.

  • @CuriousSpy

    @CuriousSpy

    Ай бұрын

    @@JeremyChone newtype is also good when you need to generate code for other platforms, like graphql or typescript

  • @JeremyChone

    @JeremyChone

    Ай бұрын

    Ha, good points. If the error type needs to be expressed in a type system that does not support algebraic types, then the decoupling might help. And, even then, we still have the different variant inner types to manage (albeit, union types on named types are easier to read than inline object types). For TS, I tend to serialize my Rust enum as "name/detail" in JSON, and I need to check if the toJSON schema can inline the type so that the JSON schema to TS type can express the correct structure. However, I typically concentrate on making the Rust part as clean and idiomatic as possible, and treat those external parts as "followers," and I am willing to make some concessions for them. But different approaches are valid as well.

  • @kuqmua755
    @kuqmua755Ай бұрын

    Really hate Result type alias concept

  • @JeremyChone

    @JeremyChone

    Ай бұрын

    I grew to really like it.

  • @nubunto

    @nubunto

    Ай бұрын

    Why tho, genuinely interested in your thoughts

Келесі