mirror of
https://github.com/NixOS/nix.git
synced 2025-11-08 19:46:02 +01:00
C API: Document and verify NIX_ERR_KEY behavior
This commit is contained in:
parent
3d777eb37f
commit
d0b1caf53a
2 changed files with 64 additions and 4 deletions
|
|
@ -423,6 +423,55 @@ TEST_F(nix_api_expr_test, nix_expr_primop_bad_return_thunk)
|
|||
ASSERT_THAT(nix_err_msg(nullptr, ctx, nullptr), testing::HasSubstr("badReturnThunk"));
|
||||
}
|
||||
|
||||
static void primop_with_nix_err_key(
|
||||
void * user_data, nix_c_context * context, EvalState * state, nix_value ** args, nix_value * ret)
|
||||
{
|
||||
nix_set_err_msg(context, NIX_ERR_KEY, "Test error from primop");
|
||||
}
|
||||
|
||||
TEST_F(nix_api_expr_test, nix_expr_primop_nix_err_key_conversion)
|
||||
{
|
||||
// Test that NIX_ERR_KEY from a custom primop gets converted to a generic EvalError
|
||||
//
|
||||
// RATIONALE: NIX_ERR_KEY must not be propagated from custom primops because it would
|
||||
// create semantic confusion. NIX_ERR_KEY indicates missing keys/indices in C API functions
|
||||
// (like nix_get_attr_byname, nix_get_list_byidx). If custom primops could return NIX_ERR_KEY,
|
||||
// an evaluation error would be indistinguishable from an actual missing attribute.
|
||||
//
|
||||
// For example, if nix_get_attr_byname returned NIX_ERR_KEY when the attribute is present
|
||||
// but the value evaluation fails, callers expecting NIX_ERR_KEY to mean "missing attribute"
|
||||
// would incorrectly handle evaluation failures as missing attributes. In places where
|
||||
// missing attributes are tolerated (like optional attributes), this would cause the
|
||||
// program to continue after swallowing the error, leading to silent failures.
|
||||
PrimOp * primop = nix_alloc_primop(
|
||||
ctx, primop_with_nix_err_key, 1, "testErrorPrimop", nullptr, "a test primop that sets NIX_ERR_KEY", nullptr);
|
||||
assert_ctx_ok();
|
||||
nix_value * primopValue = nix_alloc_value(ctx, state);
|
||||
assert_ctx_ok();
|
||||
nix_init_primop(ctx, primopValue, primop);
|
||||
assert_ctx_ok();
|
||||
|
||||
nix_value * arg = nix_alloc_value(ctx, state);
|
||||
assert_ctx_ok();
|
||||
nix_init_int(ctx, arg, 42);
|
||||
assert_ctx_ok();
|
||||
|
||||
nix_value * result = nix_alloc_value(ctx, state);
|
||||
assert_ctx_ok();
|
||||
nix_value_call(ctx, state, primopValue, arg, result);
|
||||
|
||||
// Verify that NIX_ERR_KEY gets converted to NIX_ERR_NIX_ERROR (generic evaluation error)
|
||||
ASSERT_EQ(nix_err_code(ctx), NIX_ERR_NIX_ERROR);
|
||||
ASSERT_THAT(nix_err_msg(nullptr, ctx, nullptr), testing::HasSubstr("Error from custom function"));
|
||||
ASSERT_THAT(nix_err_msg(nullptr, ctx, nullptr), testing::HasSubstr("Test error from primop"));
|
||||
ASSERT_THAT(nix_err_msg(nullptr, ctx, nullptr), testing::HasSubstr("testErrorPrimop"));
|
||||
|
||||
// Clean up
|
||||
nix_gc_decref(ctx, primopValue);
|
||||
nix_gc_decref(ctx, arg);
|
||||
nix_gc_decref(ctx, result);
|
||||
}
|
||||
|
||||
TEST_F(nix_api_expr_test, nix_value_call_multi_no_args)
|
||||
{
|
||||
nix_value * n = nix_alloc_value(ctx, state);
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ extern "C" {
|
|||
* - NIX_OK: No error occurred (0)
|
||||
* - NIX_ERR_UNKNOWN: An unknown error occurred (-1)
|
||||
* - NIX_ERR_OVERFLOW: An overflow error occurred (-2)
|
||||
* - NIX_ERR_KEY: A key error occurred (-3)
|
||||
* - NIX_ERR_KEY: A key/index access error occurred in C API functions (-3)
|
||||
* - NIX_ERR_NIX_ERROR: A generic Nix error occurred (-4)
|
||||
*/
|
||||
enum nix_err {
|
||||
|
|
@ -83,10 +83,21 @@ enum nix_err {
|
|||
NIX_ERR_OVERFLOW = -2,
|
||||
|
||||
/**
|
||||
* @brief A key error occurred.
|
||||
* @brief A key/index access error occurred in C API functions.
|
||||
*
|
||||
* This error code is returned when a key error occurred during the function
|
||||
* execution.
|
||||
* This error code is returned when accessing a key, index, or identifier that
|
||||
* does not exist in C API functions. Common scenarios include:
|
||||
* - Setting keys that don't exist (nix_setting_get, nix_setting_set)
|
||||
* - List indices that are out of bounds (nix_get_list_byidx*)
|
||||
* - Attribute names that don't exist (nix_get_attr_byname*)
|
||||
* - Attribute indices that are out of bounds (nix_get_attr_byidx*, nix_get_attr_name_byidx)
|
||||
*
|
||||
* This error typically indicates incorrect usage or assumptions about data structure
|
||||
* contents, rather than internal Nix evaluation errors.
|
||||
*
|
||||
* @note This error code should ONLY be returned by C API functions themselves,
|
||||
* not by underlying Nix evaluation. For example, evaluating `{}.foo` in Nix
|
||||
* will throw a normal error (NIX_ERR_NIX_ERROR), not NIX_ERR_KEY.
|
||||
*/
|
||||
NIX_ERR_KEY = -3,
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue