From c79ff97c072d46931a9434692d8270198f80095c Mon Sep 17 00:00:00 2001 From: Artemis Tosini Date: Tue, 10 Feb 2026 12:37:49 -0500 Subject: [PATCH] Move nix::handleExceptions to libutil This is a fairly simple function, isolated from the rest of libmain and could be useful if new programs are made that are not part of the main nix-cli subproject. --- src/libmain/include/nix/main/shared.hh | 2 -- src/libmain/shared.cc | 29 ------------------------- src/libutil/error.cc | 30 ++++++++++++++++++++++++++ src/libutil/include/nix/util/error.hh | 10 +++++++++ 4 files changed, 40 insertions(+), 31 deletions(-) diff --git a/src/libmain/include/nix/main/shared.hh b/src/libmain/include/nix/main/shared.hh index 43069ba82bd..9554a51d587 100644 --- a/src/libmain/include/nix/main/shared.hh +++ b/src/libmain/include/nix/main/shared.hh @@ -13,8 +13,6 @@ namespace nix { -int handleExceptions(const std::string & programName, std::function fun); - /** * Don't forget to call initPlugins() after settings are initialized! * @param loadConfig Whether to load configuration from `nix.conf`, `NIX_CONFIG`, etc. May be disabled for unit tests. diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc index e7a31210509..64498d8f46a 100644 --- a/src/libmain/shared.cc +++ b/src/libmain/shared.cc @@ -312,35 +312,6 @@ void printVersion(const std::string & programName) throw Exit(); } -int handleExceptions(const std::string & programName, std::function fun) -{ - ReceiveInterrupts receiveInterrupts; // FIXME: need better place for this - - ErrorInfo::programName = baseNameOf(programName); - - std::string error = ANSI_RED "error:" ANSI_NORMAL " "; - try { - fun(); - } catch (Exit & e) { - return e.status; - } catch (UsageError & e) { - logError(e.info()); - printError("Try '%1% --help' for more information.", programName); - return 1; - } catch (BaseError & e) { - logError(e.info()); - return e.info().status; - } catch (std::bad_alloc & e) { - printError(error + "out of memory"); - return 1; - } catch (std::exception & e) { - printError(error + e.what()); - return 1; - } - - return 0; -} - RunPager::RunPager() { if (!isatty(STDOUT_FILENO)) diff --git a/src/libutil/error.cc b/src/libutil/error.cc index 35e42823ce6..c42cbd5a13e 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -2,6 +2,7 @@ #include "nix/util/error.hh" #include "nix/util/environment-variables.hh" +#include "nix/util/exit.hh" #include "nix/util/signals.hh" #include "nix/util/terminal.hh" #include "nix/util/position.hh" @@ -455,4 +456,33 @@ void unreachable(std::source_location loc) panic(std::string_view(buf, std::min(static_cast(sizeof(buf)), n))); } +int handleExceptions(const std::string & programName, std::function fun) +{ + ReceiveInterrupts receiveInterrupts; // FIXME: need better place for this + + ErrorInfo::programName = baseNameOf(programName); + + std::string error = ANSI_RED "error:" ANSI_NORMAL " "; + try { + fun(); + } catch (Exit & e) { + return e.status; + } catch (UsageError & e) { + logError(e.info()); + printError("Try '%1% --help' for more information.", programName); + return 1; + } catch (BaseError & e) { + logError(e.info()); + return e.info().status; + } catch (std::bad_alloc & e) { + printError(error + "out of memory"); + return 1; + } catch (std::exception & e) { + printError(error + e.what()); + return 1; + } + + return 0; +} + } // namespace nix diff --git a/src/libutil/include/nix/util/error.hh b/src/libutil/include/nix/util/error.hh index 74bb3e4f46a..284cded8ea9 100644 --- a/src/libutil/include/nix/util/error.hh +++ b/src/libutil/include/nix/util/error.hh @@ -333,6 +333,16 @@ void throwExceptionSelfCheck(); [[noreturn]] void panic(std::string_view msg); +/** + * Run a function, printing an error and returning on exception. + * Useful for wrapping a `main` function that may throw + * + * @param programName Name of program, usually argv[0] + * @param fun Function to run inside the try block + * @return exit code: 0 if success, 1 if exception does not specify. + */ +int handleExceptions(const std::string & programName, std::function fun); + /** * Print a basic error message with source position and std::terminate(). *