Preserve type of rethrown exceptions

This commit is contained in:
Chuck 2019-09-06 11:37:48 -07:00 committed by Linus Heckemann
parent d89ccc1554
commit c7c684aaa3

View File

@ -1,10 +1,12 @@
#include <nix/config.h> // for nix/globals.hh's reference to SYSTEM #include <nix/config.h> // for nix/globals.hh's reference to SYSTEM
#include <exception> // for exception_ptr, current_exception
#include <functional> // for function #include <functional> // for function
#include <iostream> // for operator<<, basic_ostream, ostrin... #include <iostream> // for operator<<, basic_ostream, ostrin...
#include <iterator> // for next #include <iterator> // for next
#include <list> // for _List_iterator #include <list> // for _List_iterator
#include <memory> // for allocator, unique_ptr, make_unique #include <memory> // for allocator, unique_ptr, make_unique
#include <new> // for operator new
#include <nix/args.hh> // for argvToStrings, UsageError #include <nix/args.hh> // for argvToStrings, UsageError
#include <nix/attr-path.hh> // for findAlongAttrPath #include <nix/attr-path.hh> // for findAlongAttrPath
#include <nix/attr-set.hh> // for Attr, Bindings, Bindings::iterator #include <nix/attr-set.hh> // for Attr, Bindings, Bindings::iterator
@ -166,19 +168,19 @@ std::string const appendPath(std::string const & prefix, std::string const & suf
bool forbiddenRecursionName(std::string name) { return (!name.empty() && name[0] == '_') || name == "haskellPackages"; } bool forbiddenRecursionName(std::string name) { return (!name.empty() && name[0] == '_') || name == "haskellPackages"; }
void recurse(const std::function<bool(std::string const & path, std::variant<Value, Error>)> & f, Context * ctx, void recurse(const std::function<bool(std::string const & path, std::variant<Value, std::exception_ptr>)> & f, Context * ctx,
Value v, std::string const & path) Value v, std::string const & path)
{ {
std::variant<Value, Error> evaluated; std::variant<Value, std::exception_ptr> evaluated;
try { try {
evaluated = evaluateValue(ctx, &v); evaluated = evaluateValue(ctx, &v);
} catch (Error & e) { } catch (Error &) {
evaluated = e; evaluated = std::current_exception();
} }
if (!f(path, evaluated)) { if (!f(path, evaluated)) {
return; return;
} }
if (std::holds_alternative<Error>(evaluated)) { if (std::holds_alternative<std::exception_ptr>(evaluated)) {
return; return;
} }
Value const & evaluated_value = std::get<Value>(evaluated); Value const & evaluated_value = std::get<Value>(evaluated);
@ -197,8 +199,8 @@ void recurse(const std::function<bool(std::string const & path, std::variant<Val
void mapOptions(const std::function<void(std::string const & path)> & f, Context * ctx, Value root) void mapOptions(const std::function<void(std::string const & path)> & f, Context * ctx, Value root)
{ {
recurse( recurse(
[f, ctx](std::string const & path, std::variant<Value, Error> v) { [f, ctx](std::string const & path, std::variant<Value, std::exception_ptr> v) {
bool isOpt = std::holds_alternative<Error>(v) || isOption(ctx, std::get<Value>(v)); bool isOpt = std::holds_alternative<std::exception_ptr>(v) || isOption(ctx, std::get<Value>(v));
if (isOpt) { if (isOpt) {
f(path); f(path);
} }
@ -228,19 +230,19 @@ void mapOptions(const std::function<void(std::string const & path)> & f, Context
// users.users.nixbld1 = ... .. ... // users.users.nixbld1 = ... .. ...
// ... // ...
// users.users.systemd-timesync = ... .. ... // users.users.systemd-timesync = ... .. ...
void mapConfigValuesInOption(const std::function<void(std::string const & path, std::variant<Value, Error> v)> & f, void mapConfigValuesInOption(const std::function<void(std::string const & path, std::variant<Value, std::exception_ptr> v)> & f,
std::string const & path, Context * ctx) std::string const & path, Context * ctx)
{ {
Value * option; Value * option;
try { try {
option = findAlongAttrPath(*ctx->state, path, *ctx->autoArgs, ctx->config_root); option = findAlongAttrPath(*ctx->state, path, *ctx->autoArgs, ctx->config_root);
} catch (Error & e) { } catch (Error &) {
f(path, e); f(path, std::current_exception());
return; return;
} }
recurse( recurse(
[f, ctx](std::string const & path, std::variant<Value, Error> v) { [f, ctx](std::string const & path, std::variant<Value, std::exception_ptr> v) {
bool leaf = std::holds_alternative<Error>(v) || std::get<Value>(v).type != tAttrs || bool leaf = std::holds_alternative<std::exception_ptr>(v) || std::get<Value>(v).type != tAttrs ||
ctx->state->isDerivation(std::get<Value>(v)); ctx->state->isDerivation(std::get<Value>(v));
if (!leaf) { if (!leaf) {
return true; // Keep digging return true; // Keep digging
@ -273,7 +275,7 @@ Value parseAndEval(EvalState * state, std::string const & expression, std::strin
return v; return v;
} }
void printValue(Context * ctx, Out & out, std::variant<Value, Error> maybe_value, std::string const & path); void printValue(Context * ctx, Out & out, std::variant<Value, std::exception_ptr> maybe_value, std::string const & path);
void printList(Context * ctx, Out & out, Value & v) void printList(Context * ctx, Out & out, Value & v)
{ {
@ -331,11 +333,11 @@ void printMultiLineString(Out & out, Value const & v)
} }
} }
void printValue(Context * ctx, Out & out, std::variant<Value, Error> maybe_value, std::string const & path) void printValue(Context * ctx, Out & out, std::variant<Value, std::exception_ptr> maybe_value, std::string const & path)
{ {
try { try {
if (std::holds_alternative<Error>(maybe_value)) { if (std::holds_alternative<std::exception_ptr>(maybe_value)) {
throw Error{std::get<Error>(maybe_value)}; std::rethrow_exception(std::get<std::exception_ptr>(maybe_value));
} }
Value v = evaluateValue(ctx, &std::get<Value>(maybe_value)); Value v = evaluateValue(ctx, &std::get<Value>(maybe_value));
if (ctx->state->isDerivation(v)) { if (ctx->state->isDerivation(v)) {
@ -366,7 +368,7 @@ void printValue(Context * ctx, Out & out, std::variant<Value, Error> maybe_value
} }
} }
void printConfigValue(Context * ctx, Out & out, std::string const & path, std::variant<Value, Error> v) void printConfigValue(Context * ctx, Out & out, std::string const & path, std::variant<Value, std::exception_ptr> v)
{ {
out << path << " = "; out << path << " = ";
printValue(ctx, out, std::move(v), path); printValue(ctx, out, std::move(v), path);
@ -378,7 +380,7 @@ void printAll(Context * ctx, Out & out)
mapOptions( mapOptions(
[ctx, &out](std::string const & option_path) { [ctx, &out](std::string const & option_path) {
mapConfigValuesInOption( mapConfigValuesInOption(
[ctx, &out](std::string const & config_path, std::variant<Value, Error> v) { [ctx, &out](std::string const & config_path, std::variant<Value, std::exception_ptr> v) {
printConfigValue(ctx, out, config_path, v); printConfigValue(ctx, out, config_path, v);
}, },
option_path, ctx); option_path, ctx);