Olivia 🦀
banner
iolivia.me
Olivia 🦀
@iolivia.me
👩‍💻 staff eng
🦀 post a lot about rust and rust gamedev
✍️ wrote https://sokoban.iolivia.me
🔥 blog at https://iolivia.me

🧵 weekly #rustlang threads every Thursday - subscribe here https://forms.gle/Tcm7cAkLt4NF9ZCZ9
That's it, we looked at how to do basic error handling in rust and then improved it using anyhow for context and thiserror w error types.

Hope it helped you learn 1% more Rust today, follow me for more threads like this and subscribe to receive these threads over email forms.gle/vY6zXE21Dkwa... 🦋 🦀
Rust Threads Newsletter
Get bite-size Rust Threads about fundamental concepts and practical usage right in your inbox every Thursday. Checkout this for a sample of previous threads:…
forms.gle
October 30, 2025 at 8:05 AM
💡 This is the key difference: anyhow is great for applications where you just need good error messages, while thiserror is perfect for libraries where consumers need to handle errors programmatically.
October 30, 2025 at 8:05 AM
The error messages are now cleaner and more structured. With custom error types, library clients can:
- Match on specific error variants to handle different cases
- Access error fields programmatically (like student_id, course_id)
- Make informed decisions based on the error type
October 30, 2025 at 8:05 AM
Then, we change all instances of anyhow! to return the appropriate EnrollmentError variant, and change the function signatures to return Result<T, EnrollmentError>. Note that we can no longer use `.context()` since that's an anyhow feature, but the errors themselves need to be descriptive enough
October 30, 2025 at 8:05 AM
and we wanted to expose more specific error types that clients can match on and handle differently, we need custom error types. We can use the thiserror::Error derive macro to easily create a custom error enum with different variants for each error case.
October 30, 2025 at 8:05 AM
3️⃣ Custom error types

The course enrollment is a pretty representative complex example, and the solution with anyhow context is normally good enough for internal application code where you don't need to worry about exposing error types to external clients

However, if this was a library ...
October 30, 2025 at 8:05 AM
We could extend this to a more complex example like course enrollment with a deeper chain. Here's how the process_enrollment function uses context at multiple levels.

Notice how each layer of context provides additional info about where in the call stack the error occurred.
October 30, 2025 at 8:05 AM
You can see in the last error the top level error message is "Failed to add student with id 2" and the cause is "Name cannot be empty". This additional context is super helpful for complex chains of function calls.
October 30, 2025 at 8:05 AM
2️⃣ Anyhow context

Let's add new functionality that also validates the student name before adding them to the db. First, we need to import the Context trait and then use .context() to add context to the error returned from validate_name.
October 30, 2025 at 8:05 AM
This is already better than the plain result because:
- anyhow::Result can hold any error type, not just String
- We get better error trait implementations (Display, Debug, etc.)
- We can return different error types from the same function
- It sets us up to use anyhow's powerful context feature
October 30, 2025 at 8:05 AM
1️⃣ Using Anyhow

Building on top of this, let's explore how anyhow can help improve our error handling from here. We first switch Result<Student, String> to anyhow::Result<Student> and use the anyhow::anyhow! macro to create errors with messages.
October 30, 2025 at 8:05 AM
Version 1 - Naive approach with panic-crashes the whole program on a simple error
Version 2 - Returning bool to indicate success/failure but no error details, we know what failed but not why
Version 3 - Using Result to return success values and error details, a good compromise and the rust default
October 30, 2025 at 8:05 AM
0️⃣ The evolution from panic to Result

Let's explore error handling approaches using a university database with Student and Course structs, and a Database holding students, courses and an enrollments HashMap.

Now let's explore 3 implementations for error handling:
V1 - Panic
V2 - Bool
V3 - Result
October 30, 2025 at 8:05 AM
Thank you so much! 🙏

Been struggling a bit with schedule last few weeks so every bit of feedback helps to keep the motivation up 😀
October 27, 2025 at 12:32 PM
Ah yes, here you go! bsky.app/profile/ioli...

I am planning to bundle them into blog posts and/or a PDF eventually!
👻 Understanding PhantomData in #rustlang 🦀

Ever wondered how to create a type that depends on another type but doesn't actually contain it?

Let's explore PhantomData with a practical example of a course grading system! 👇 🧵
October 26, 2025 at 9:30 AM
That's it, we learned how to use the std::fs module for basic file IO operations in Rust.

Hope it helped you learn 1% more Rust today, follow me for more threads like this and subscribe to receive these threads over email forms.gle/vY6zXE21Dkwa... 🦋 🦀
Rust Threads Newsletter
Get bite-size Rust Threads about fundamental concepts and practical usage right in your inbox every Thursday. Checkout this for a sample of previous threads:…
forms.gle
October 10, 2025 at 9:17 AM
🚀 Quick recap:
- Use fs::write or writeln! for writing files
- Use create_dir_all before writing to nested paths
- Use fs::read_to_string for reading small files and BufReader for larger files
- Use remove_file/remove_dir to delete files and directories
October 10, 2025 at 9:17 AM
The reader acts as an iterator over the lines in the file, which means it never loads the full file into memory at once, but rather reads it line by line or chunks
October 10, 2025 at 9:17 AM
7️⃣ Reading larger files

For larger files, it's better to use a buffered reader to avoid loading the entire file into memory. Here's how you can do that. Notice we use the BufReader and BufRead trait.
October 10, 2025 at 9:17 AM
6️⃣ Deleting a file

After we saw how to create, write, and read files, let's see how to delete a file, pretty simple! We could also use the equivalent for directories with fs::remove_dir or fs::remove_dir_all.
October 10, 2025 at 9:17 AM
5️⃣ Parsing contents into structured data

Technically not part of the std::fs API but another common pattern is to read a file and then parse its contents into a structured format. Here's how we can read back the grades file. We could also use JSON/CSV+real parser, this is just a simple example.
October 10, 2025 at 9:17 AM