Replace eyre catch-alls with structured error types in application crates#1761
Replace eyre catch-alls with structured error types in application crates#1761Ericson2314 wants to merge 1 commit into
eyre catch-alls with structured error types in application crates#1761Conversation
4365bd2 to
a0097ea
Compare
| .tls_config(tls)? | ||
| .connect() | ||
| .await | ||
| .context("Failed to establish connection with Channel")? |
There was a problem hiding this comment.
Do we loose error context in cases like this where you prune the error message? I found it quiet useful to have errors at every step.
There was a problem hiding this comment.
Yeah I think the WithContext thing needs to be used in more places.
There was a problem hiding this comment.
The solution is to divide errors by cause, not type. The information that would be put in context should be put in the message with #[error("message")], and the variant should include the relevant source with #[source].
| current_bytes: fs_err::read_to_string(cgroups_path.join("memory.current"))? | ||
| .trim() | ||
| .parse() | ||
| .context("memory current parsing failed")?, |
There was a problem hiding this comment.
Same question here. I haven't read the whole error hierarchy to understand what impact this has on error messages.
Could you write pull request messages yourself, if you expect me to review them? |
a0097ea to
5491b18
Compare
5491b18 to
60f07d0
Compare
bc36c74 to
f4fb0fc
Compare
anyhow with structured error types in application crateseyre catch-alls with structured error types in application crates
…crates The previous commits moved the application crates off `anyhow` onto `eyre`/`color-eyre`, but only at the reporting boundary — most function signatures still returned a catch-all `eyre::Result`. Now every function returns the narrowest error type that covers its actual failure modes. This makes it possible to distinguish infrastructure failures (DB down, store unreachable) from logic errors (step not found in queue, drv lookup miss) at the type level. Among other benefits, this will assist the "fail-fast" PR in deciding what is fatal vs recoverable, and making sure those decisions are consistent and enforced. Error types are co-located with the functions that produce them, using split `impl State` blocks where needed. The fine-grained sub-enums (e.g. `ResolutionError`, `StepLookupError`, `MachineLookupError`, `DrvLookupError`) might seem like overkill in a single 2500-line `state/mod.rs`, but they are designed so that a future file split (e.g. `state/resolution.rs`, `state/step_completion.rs`) would give each sub-module its own natural error type, with `StateLogicError` in `mod.rs` just re-exporting them. The error hierarchy becomes the module hierarchy. Similarly, the builder's per-phase error types (`BuildError`, `ImportError`, `UploadError`, `BuildOutputParseError`, `ResultInfoError`) are each defined next to the free functions they belong to, and `JobFailure` ties them together by build phase. A future split into `import.rs`, `upload.rs`, etc. would be straightforward. In the same spirit, `NarInfoError::InvalidValue` in `binary-cache` no longer erases its cause behind a `Box<dyn Error>`; a new `InvalidValueError` enum names the two concrete parse failures (`ParseStorePathError`, `ParseIntError`) that can actually occur. `color-eyre` remains only at the binary boundary: `main` still returns `color_eyre::Result` so fatal errors render with the full source chain, and a few `BuilderError` variants (`LoadNixConfig`, `ReadingSystemInfo`, `HandlingRequest`) still carry `eyre::Report` sources where the underlying code has not been typed yet. Examples switch from `anyhow` to `eyre` (non-workspace `[dev-dependencies]`), keeping `anyhow` out of the dependency tree.
f4fb0fc to
f31950b
Compare
See commit message