Seeking Best Practices for Error and Warning Handling in Complex Rust Projects
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 20/100
- Issue type
- Documentation
- Clarity
- Needs clarification
- Activity status
- Stale
- Tech stack
- rust
- Domain
- documentation
Research direction
Start by reading the referenced crates/core/src/error.rs file in rustic_core and compare its current error and warning types with the questions in this issue. A contribution would need a defined documentation scope and agreement on the intended patterns; this issue does not specify a concrete page, example, or acceptance criteria.
Written by the indexing model from the issue text.
Description
Hi @nrc!
I’m reaching out to get some expert advice on the challenges we’re facing with error and warning handling in our Rust-based project, rustic_core. Our project is relatively complex, and we’re struggling to find the right balance between propagating errors (soft- and hard errors), handling warnings, and maintaining good user experience with clear error messages.
Context of Our Problem
-
Error Handling:
- In our current setup, we primarily rely on returning
Result<T, RusticError>to propagate errors. Kind of a god enum approach, where we convert sub errors into that god error for handing it over at our API boundary. However, we often find ourselves in scenarios where multiple errors can occur (e.g., batch operations or validation processes of data collections), and handling only the first error results in lost context. - We are considering three primary options:
- Returning a single error (
Result<T, RusticError>) - Returning a list of errors (
Result<T, Vec<RusticError>>) - Returning nested Results (
Result<Result<T, Vec<RusticSoftError>>, RusticHardError>)
- Returning a single error (
- We're also facing cases where we need to continue execution in the presence of some errors but fail fast in others.
- In our current setup, we primarily rely on returning
-
Warning Handling:
- We need a consistent way to handle warnings. So far, we’ve identified three potential approaches:
- Logging warnings locally and not passing them back to the caller.
- Returning a boolean flag (
is_warn) to indicate if warnings occurred. - Returning a list of warnings to provide detailed information about all non-critical issues that the caller can process.
- We’re trying to decide if warnings should be purely for operational visibility (handled via logging), or if the caller should be made aware of warnings explicitly.
- We need a consistent way to handle warnings. So far, we’ve identified three potential approaches:
-
General Pain Points:
- We struggle with missing contextual information in error messages, leaving the end-users without actionable guidance.
- We want to include error codes or links to documentation in error messages for better guidance and debugging.
- In scenarios like async operations, the logging and error handling become more difficult to manage, especially when errors are collected from multiple spawned tasks.
- Finally, we want to reconsider how we handle warnings and errors over function boundaries, thinking we may need to simplify or keep more localized handling without propagating too much information upward.
Questions
-
Error Propagation:
- When should we prefer returning a single error (e.g.,
Result<T, RusticError>) vs. returning a list of errors (e.g.,Result<T, Vec<RusticError>>)? Are there performance or architectural concerns that we should consider when deciding between these two approaches? - In complex async operations or batch processing, where multiple errors might occur, what would be the best way to handle error accumulation without losing key context? Is there a common pattern in Rust for handling this elegantly? Like spawning an error handling thread and communicating with it via a channel?
- When should we prefer returning a single error (e.g.,
-
Warnings:
- When handling warnings, would you recommend keeping them local (i.e., logging only) or propagating them back to the caller? Under what circumstances is it better to pass warnings up vs. treating them as internal operational feedback?
- How would you handle situations where a function should continue executing but may want to indicate that warnings occurred (e.g., via an
is_warnboolean flag or a list of warnings)? What is the best approach here to maintain simplicity while giving the caller enough control over decision-making?
-
Async/Concurrency:
- In async tasks and concurrent operations, how do you typically manage error propagation and structured logging, especially when errors are collected from multiple spawned tasks? How can we ensure we get full visibility into errors without complicating error management?
-
General Best Practices:
- Are there any best practices or patterns you would recommend for error and warning handling that balance performance, code maintainability, and user experience in Rust-based systems?
- How can we maintain a simple API for callers while ensuring we capture all relevant issues (both errors and warnings) during complex or long-running operations?
- We also thought about a nested Result where the outer Result can contain hard errors that lead to aborting the program. While the inner Result would contain a list of errors that were coming up during the processing of data collections. Which is inspired by http://sled.rs/errors
We appreciate any guidance or patterns you’ve found useful in these situations!
- Dominant language
- No language data
- Stars
- 51
- Forks
- 4
- PR merge metrics
- No merged PRs in 30d
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from nrc/error-docs
-
Difficulty 2/5 1-3 hours Newbie friendliness 55/100
nrc/error-docs#16 ·
-
Difficulty 4/5 3-5 days Newbie friendliness 25/100
nrc/error-docs#13 ·
-
Collected feedback Open
Difficulty 5/5 Over a week Newbie friendliness 15/100
nrc/error-docs#11 · 8 comments ·
-
Difficulty 3/5 1-2 days Newbie friendliness 45/100
nrc/error-docs#3 ·
-
Case studies Open
Difficulty 4/5 3-5 days Newbie friendliness 25/100
nrc/error-docs#1 · 1 comment ·
Similar issues
-
Difficulty 1/5 Under an hour Newbie friendliness 95/100
Git-it-App/git-it-electron#1047 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
neondatabase/website#5944 ·
-
📕documentation
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
db-ux-design-system/core-web#8239 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
libsdl-org/sdlwiki#1008 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 70/100