Skip to content

Fix after updating nix#21

Merged
RossComputerGuy merged 2 commits into
integrationfrom
fix/build-after-flake-update
May 7, 2026
Merged

Fix after updating nix#21
RossComputerGuy merged 2 commits into
integrationfrom
fix/build-after-flake-update

Conversation

@RossComputerGuy
Copy link
Copy Markdown
Member

@RossComputerGuy RossComputerGuy commented Apr 28, 2026

Summary by CodeRabbit

  • Bug Fixes

    • Improved error propagation in expression evaluation to correctly handle recoverable errors.
    • Enhanced error type detection for compatibility with newer Nix versions.
  • Tests

    • Updated tests to validate recoverable error handling and propagation; some tests are now skipped in environments where recoverable errors aren’t retried.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 28, 2026

Caution

Review failed

Failed to post review comments

📝 Walkthrough

Walkthrough

Tests now return boxed NixBindingsError::RecoverableError and propagate potential errors via Ok(es.new_value_int(42)?); primop.rs adds a NixError alias for nix_bindings_util::Error under nix_at_least = "2.34.0pre" to disambiguate downcasts.

Changes

Recoverable Primop Tests

Layer / File(s) Summary
Test Attributes
nix-bindings-expr/src/eval_state.rs
Added #[ignore = "recoverable primop errors not retried"] to two recoverable-error tests.
Test Failure Path
nix-bindings-expr/src/eval_state.rs
Failure branches now return Box::new(NixBindingsError::RecoverableError("transient failure")).
Test Success Path
nix-bindings-expr/src/eval_state.rs
Success branches now return Ok(es.new_value_int(42)?) to propagate potential errors through the thunk Result.

Primop Error Type Disambiguation

Layer / File(s) Summary
Type Alias
nix-bindings-expr/src/primop.rs
Under nix_at_least = "2.34.0pre", introduced type NixError = nix_bindings_util::Error; and updated downcast logic to use NixError instead of the ambiguous Error.
Error Mapping
nix-bindings-expr/src/primop.rs
Detection of RecoverableError now downcasts to NixError and maps it to raw_util::err_NIX_ERR_RECOVERABLE.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 I nibble code with careful bite,
Errors named to make things right,
Tests now whisper, "try once more,"
Aliases clear the murky floor,
Hopping on, my patch takes flight ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Fix after updating nix' is vague and does not clearly convey what was actually changed or fixed. While it references updating nix, it lacks specificity about the actual nature of the fixes (type aliasing, test updates, error handling). Revise the title to be more specific about the primary changes, such as 'Fix type alias and test updates after nix version upgrade' or 'Update error handling and tests for nix compatibility'.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/build-after-flake-update

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@nix-bindings-expr/src/eval_state.rs`:
- Around line 2981-2986: The test labeled "*_in_chain" is supposed to exercise a
chained recoverable error but the code currently returns
Err(Box::new(NixBindingsError::RecoverableError(String::from("transient
failure")))) directly; update the code in eval_state.rs so the RecoverableError
is created with a wrapped source (e.g., use std::error::Error::source or create
a nested error and attach it as the source) instead of returning it directly,
ensuring the chain is exercised (or alternatively, if you prefer to change the
test intent, rename the test and update its comment to reflect that it no longer
checks chaining); locate the case that currently returns
Err(...RecoverableError(...)) near es.new_value_int(42)? and either wrap that
RecoverableError around another error instance or update the test name/comment
accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5b22263b-dee0-4726-9321-af2ed3dd53c2

📥 Commits

Reviewing files that changed from the base of the PR and between 45a57d9 and 4799da4.

⛔ Files ignored due to path filters (1)
  • flake.lock is excluded by !**/*.lock
📒 Files selected for processing (2)
  • nix-bindings-expr/src/eval_state.rs
  • nix-bindings-expr/src/primop.rs

Comment on lines +2981 to 2986
Err(Box::new(NixBindingsError::RecoverableError(String::from(
"transient failure",
))))
} else {
es.new_value_int(42)
Ok(es.new_value_int(42)?)
}
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot Apr 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

*_in_chain test no longer exercises chained recoverable errors.

Line 2980 says this case wraps recoverable errors in a chain, but Lines 2981-2983 now return the recoverable error directly. This makes the test behavior effectively duplicate the previous recoverable test.

Consider either restoring an actual wrapped source error here, or renaming/updating the test intent and comments.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@nix-bindings-expr/src/eval_state.rs` around lines 2981 - 2986, The test
labeled "*_in_chain" is supposed to exercise a chained recoverable error but the
code currently returns
Err(Box::new(NixBindingsError::RecoverableError(String::from("transient
failure")))) directly; update the code in eval_state.rs so the RecoverableError
is created with a wrapped source (e.g., use std::error::Error::source or create
a nested error and attach it as the source) instead of returning it directly,
ensuring the chain is exercised (or alternatively, if you prefer to change the
test intent, rename the test and update its comment to reflect that it no longer
checks chaining); locate the case that currently returns
Err(...RecoverableError(...)) near es.new_value_int(42)? and either wrap that
RecoverableError around another error instance or update the test name/comment
accordingly.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Except we have to do Ok(...?) because of this:

error: Cannot build '/nix/store/h59dqnbiyq4nclkyjz3qa713qlapyiyi-nix-bindings-expr-0.2.1.drv'.
       Reason: builder failed with exit code 101.
       Output paths:
         /nix/store/z42cczb2w72c9gvqf9x6kjnd0d6gddx3-nix-bindings-expr-0.2.1
       Last 25 log lines:
       > 2943 | ...                   es.new_value_int(42)
       >      |                       ^^^^^^^^^^^^^^^^^^^^ expected `Result<Value, Box<dyn Error>>`, found `Result<Value, EvalStateError>`
       >      |
       >      = note: expected enum `std::result::Result<_, Box<(dyn std::error::Error + 'static)>>`
       >                 found enum `std::result::Result<_, eval_state::EvalStateError>`
       > help: use `?` to coerce and return an appropriate `Err`, and wrap the resulting value in `Ok` so the expression remains of type `Result`
       >      |
       > 2943 |                             Ok(es.new_value_int(42)?)
       >      |                             +++                    ++
       >
       > error[E0308]: mismatched types
       >     --> nix-bindings-expr/src/eval_state.rs:2985:29
       >      |
       > 2985 | ...                   es.new_value_int(42)
       >      |                       ^^^^^^^^^^^^^^^^^^^^ expected `Result<Value, Box<dyn Error>>`, found `Result<Value, EvalStateError>`
       >      |
       >      = note: expected enum `std::result::Result<_, Box<(dyn std::error::Error + 'static)>>`
       >                 found enum `std::result::Result<_, eval_state::EvalStateError>`
       > help: use `?` to coerce and return an appropriate `Err`, and wrap the resulting value in `Ok` so the expression remains of type `Result`
       >      |
       > 2985 |                             Ok(es.new_value_int(42)?)
       >      |                             +++                    ++
       >
       > For more information about this error, try `rustc --explain E0308`.
       > error: could not compile `nix-bindings-expr` (lib test) due to 2 previous errors
       For full logs, run:
         nix log /nix/store/h59dqnbiyq4nclkyjz3qa713qlapyiyi-nix-bindings-expr-0.2.1.drv

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RossComputerGuy, understood — the Ok(es.new_value_int(42)?) change is clearly a required fix for the type mismatch (Result<Value, EvalStateError> vs Result<Value, Box<dyn Error>>). That part is correct.

My concern about the _in_chain test is actually separate and still stands: the inline comment on Line ~2980 says "Wrap RecoverableError in .context(), pushing it down the chain", but neither the old code nor the new code actually wraps the error in a chain — both return a RecoverableError directly. This makes the _in_chain test functionally equivalent to eval_state_primop_recoverable_error, and the stale comment is misleading.

Would you be open to either:

  1. Updating just the comment to remove the chain-wrapping claim, or
  2. Actually wrapping the error so the chain is exercised, e.g.:
// count == 0 branch
Err(Box::new(NixBindingsError::RecoverableError(String::from(
    "transient failure",
))) as Box<dyn std::error::Error>)
// or with a genuine wrapper:
{
    #[derive(Debug)]
    struct Wrapper(Box<dyn std::error::Error + Send + Sync>);
    impl std::fmt::Display for Wrapper {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.0.fmt(f) }
    }
    impl std::error::Error for Wrapper {
        fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { Some(&*self.0) }
    }
    Err(Box::new(Wrapper(Box::new(NixBindingsError::RecoverableError(String::from("transient failure"))))))
}

If chaining is the actual intended behavior to test, option 2 ensures the source() traversal in the recoverable-error detection path is exercised. If the test is just about retry-on-recoverable, option 1 (comment fix + possible rename) would suffice.


🧠 Learnings used
Learnt from: RossComputerGuy
Repo: DeterminateSystems/nix-bindings-rust PR: 12
File: nix-bindings-store/src/store.rs:275-287
Timestamp: 2026-02-23T23:55:07.470Z
Learning: The nix-bindings-rust project's minimum supported Nix version is 2.26, particularly for the fetchers. While some functionality may work with earlier versions, they are not tested or officially supported.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no .context() function because that was from upstream using anyhow, this fork does not use anyhow.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RossComputerGuy, thanks for the context — that clears it up. The stale comment is a leftover from upstream's anyhow-based chaining approach, which no longer applies here.

Since the _in_chain test can't actually exercise error-source chaining without anyhow (or a hand-rolled wrapper), the simplest clean-up would be to update the test name and remove the misleading comment, since it's effectively just another retry-on-recoverable test at this point. For example:

#[test]
#[cfg(nix_at_least = "2.34.0pre")]
fn eval_state_primop_recoverable_error_retry() {  // renamed from _in_chain
    gc_registering_current_thread(|| {
        let store = Store::open(None, []).unwrap();
        let mut es = EvalState::new(store, []).unwrap();

        let call_count = std::cell::Cell::new(0u32);
        let v = es
            .new_value_thunk(
                "recoverable_chain_test",
                Box::new(move |es: &mut EvalState| {
                    let count = call_count.get();
                    call_count.set(count + 1);
                    if count == 0 {
                        Err(Box::new(NixBindingsError::RecoverableError(String::from(
                            "transient failure",
                        ))))
                    } else {
                        Ok(es.new_value_int(42)?)
                    }
                }),
            )
            .unwrap();
        // ...
    })
    .unwrap();
}

That said, if you'd prefer to leave the test as-is and just drop the misleading comment, that works too. Happy to defer to your preference.


✏️ Learnings added
Learnt from: RossComputerGuy
Repo: DeterminateSystems/nix-bindings-rust PR: 21
File: nix-bindings-expr/src/eval_state.rs:2981-2986
Timestamp: 2026-04-29T16:25:11.002Z
Learning: The nix-bindings-rust fork (DeterminateSystems/nix-bindings-rust) does not use anyhow. The `.context()` error chaining method is not available; it originated in upstream code that used anyhow. Error handling uses Box<dyn std::error::Error> and custom error types instead.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: RossComputerGuy
Repo: DeterminateSystems/nix-bindings-rust PR: 12
File: nix-bindings-store/src/store.rs:275-287
Timestamp: 2026-02-23T23:55:07.470Z
Learning: The nix-bindings-rust project's minimum supported Nix version is 2.26, particularly for the fetchers. While some functionality may work with earlier versions, they are not tested or officially supported.

@RossComputerGuy RossComputerGuy merged commit 1d65037 into integration May 7, 2026
5 checks passed
@RossComputerGuy RossComputerGuy deleted the fix/build-after-flake-update branch May 7, 2026 15:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants