Skip to content

Introduce a "failed" value type (v2)#15286

Merged
xokdvium merged 6 commits intomasterfrom
failed-values-v2
Feb 21, 2026
Merged

Introduce a "failed" value type (v2)#15286
xokdvium merged 6 commits intomasterfrom
failed-values-v2

Conversation

@xokdvium
Copy link
Contributor

Motivation

Rebased version of #13930 that addresses concerns that @roberth voiced in #13930 (review) and in other review comments. My hope is to start working on getting async/concurrent evaluation upstream and this seems like a very natural way to propagate exceptions for suspendable work.

To address the trace mutation issue each error type now has an implementation of ErrorBase::throwClone aided by a CRTP mixin CloneableError. It's a bit of a churn, but I think this is the best way forward.

Context

Closes #13930.


Add 👍 to pull requests you find important.

The Nix maintainer team uses a GitHub project board to schedule and track reviews.

@github-actions github-actions bot added with-tests Issues related to testing. PRs with tests have some priority fetching Networking with the outside (non-Nix) world, input locking c api Nix as a C library with a stable interface labels Feb 18, 2026
@xokdvium xokdvium requested review from roberth and removed request for Ericson2314 and edolstra February 18, 2026 19:55
Comment on lines +236 to +249
template<typename Derived, typename Base>
class CloneableError : public Base
{
public:
using Base::Base;

/**
* Rethrow a copy of this exception. Useful when the exception can get
* modified when appending traces.
*/
[[noreturn]] void throwClone() const override
{
throw Derived(static_cast<const Derived &>(*this));
}
Copy link
Member

Choose a reason for hiding this comment

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

A necessary but mild annoyance that looks well executed to me.

Comment on lines +18 to +19
… forcing b

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is from the initial memoised stack trace. Pretty unavoidable and adds more context.

xokdvium and others added 6 commits February 19, 2026 14:22
This is needed to make it possible to store exceptions in failed values
with each new rethrow getting a fresh copy of the exception object.
In the multithreaded evaluator, it's possible for multiple threads to
wait on the same thunk. If evaluation of the thunk results in an
exception, the waiting threads shouldn't try to re-force the thunk.
Instead, they should rethrow the same exception, without duplicating
any work.

Therefore, there is now a new value type `tFailed` that stores an
std::exception_ptr. If evaluation of a thunk/app results in an
exception, `forceValue()` overwrites the value with a `tFailed`. If
`forceValue()` encounters a `tFailed`, it rethrows the exception. So
you normally never need to check for failed values (since forcing them
causes a rethrow).

Co-authored-by: Robert Hensing <robert@roberthensing.nl>
This provides an explicit API for call-fail-retry-succeed evaluation
flows, such as currently used in NixOps4.

An alternative design would simply reset the `Value` to the original
thunk instead of `tFailed` under the condition of catching a
`RecoverableEvalError`.
That is somewhat simpler, but I believe the presence of `tFailed` is
beneficial for possible use in the repl; being able to show the error
sooner, without re-evaluation.

The hasPos method is required in order to avoid an include loop.
@xokdvium xokdvium added this pull request to the merge queue Feb 21, 2026
Merged via the queue into master with commit 614072a Feb 21, 2026
18 checks passed
@xokdvium xokdvium deleted the failed-values-v2 branch February 21, 2026 09:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c api Nix as a C library with a stable interface documentation fetching Networking with the outside (non-Nix) world, input locking with-tests Issues related to testing. PRs with tests have some priority

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants