Compare commits
1 Commits
master
...
cloneable-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2ded675e56 |
@@ -11,7 +11,7 @@
|
||||
namespace nix::eval_cache {
|
||||
|
||||
CachedEvalError::CachedEvalError(ref<AttrCursor> cursor, Symbol attr)
|
||||
: EvalError(cursor->root->state, "cached failure of attribute '%s'", cursor->getAttrPathStr(attr))
|
||||
: CloneableError(cursor->root->state, "cached failure of attribute '%s'", cursor->getAttrPathStr(attr))
|
||||
, cursor(cursor)
|
||||
, attr(attr)
|
||||
{
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace nix::eval_cache {
|
||||
struct AttrDb;
|
||||
class AttrCursor;
|
||||
|
||||
struct CachedEvalError : EvalError
|
||||
struct CachedEvalError : CloneableError<CachedEvalError, EvalError>
|
||||
{
|
||||
const ref<AttrCursor> cursor;
|
||||
const Symbol attr;
|
||||
|
||||
@@ -18,7 +18,7 @@ class EvalErrorBuilder;
|
||||
*
|
||||
* Most subclasses should inherit from `EvalError` instead of this class.
|
||||
*/
|
||||
class EvalBaseError : public Error
|
||||
class EvalBaseError : public CloneableError<EvalBaseError, Error>
|
||||
{
|
||||
template<class T>
|
||||
friend class EvalErrorBuilder;
|
||||
@@ -26,14 +26,14 @@ public:
|
||||
EvalState & state;
|
||||
|
||||
EvalBaseError(EvalState & state, ErrorInfo && errorInfo)
|
||||
: Error(errorInfo)
|
||||
: CloneableError(errorInfo)
|
||||
, state(state)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
explicit EvalBaseError(EvalState & state, const std::string & formatString, const Args &... formatArgs)
|
||||
: Error(formatString, formatArgs...)
|
||||
: CloneableError(formatString, formatArgs...)
|
||||
, state(state)
|
||||
{
|
||||
}
|
||||
@@ -60,23 +60,23 @@ MakeError(InfiniteRecursionError, EvalError);
|
||||
* Inherits from EvalBaseError (not EvalError) because resource exhaustion
|
||||
* should not be cached.
|
||||
*/
|
||||
struct StackOverflowError : public EvalBaseError
|
||||
struct StackOverflowError : public CloneableError<StackOverflowError, EvalBaseError>
|
||||
{
|
||||
StackOverflowError(EvalState & state)
|
||||
: EvalBaseError(state, "stack overflow; max-call-depth exceeded")
|
||||
: CloneableError(state, "stack overflow; max-call-depth exceeded")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
MakeError(IFDError, EvalBaseError);
|
||||
|
||||
struct InvalidPathError : public EvalError
|
||||
struct InvalidPathError : public CloneableError<InvalidPathError, EvalError>
|
||||
{
|
||||
public:
|
||||
Path path;
|
||||
|
||||
InvalidPathError(EvalState & state, const Path & path)
|
||||
: EvalError(state, "path '%s' is not valid", path)
|
||||
: CloneableError(state, "path '%s' is not valid", path)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
@@ -9,14 +9,14 @@
|
||||
|
||||
namespace nix {
|
||||
|
||||
class BadNixStringContextElem : public Error
|
||||
class BadNixStringContextElem final : public CloneableError<BadNixStringContextElem, Error>
|
||||
{
|
||||
public:
|
||||
std::string_view raw;
|
||||
|
||||
template<typename... Args>
|
||||
BadNixStringContextElem(std::string_view raw_, const Args &... args)
|
||||
: Error("")
|
||||
: CloneableError("")
|
||||
{
|
||||
raw = raw_;
|
||||
auto hf = HintFmt(args...);
|
||||
|
||||
@@ -1312,11 +1312,12 @@ static void prim_warn(EvalState & state, const PosIdx pos, Value ** args, Value
|
||||
state.forceString(*args[0], pos, "while evaluating the first argument; the message passed to builtins.warn");
|
||||
|
||||
{
|
||||
BaseError msg(std::string{msgStr});
|
||||
msg.atPos(state.positions[pos]);
|
||||
auto info = msg.info();
|
||||
info.level = lvlWarn;
|
||||
info.isFromExpr = true;
|
||||
ErrorInfo info{
|
||||
.level = lvlWarn,
|
||||
.msg = HintFmt(std::string(msgStr)),
|
||||
.pos = state.positions[pos],
|
||||
.isFromExpr = true,
|
||||
};
|
||||
logWarning(info);
|
||||
}
|
||||
|
||||
|
||||
@@ -74,11 +74,11 @@ namespace nix {
|
||||
|
||||
struct GitSourceAccessor;
|
||||
|
||||
struct GitError : public Error
|
||||
struct GitError final : public CloneableError<GitError, Error>
|
||||
{
|
||||
template<typename... Ts>
|
||||
GitError(const git_error & error, Ts &&... args)
|
||||
: Error("")
|
||||
: CloneableError("")
|
||||
{
|
||||
auto hf = HintFmt(std::forward<Ts>(args)...);
|
||||
err.msg = HintFmt("%1%: %2% (libgit2 error code = %3%)", Uncolored(hf.str()), error.message, error.klass);
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
namespace nix {
|
||||
|
||||
AwsAuthError::AwsAuthError(int errorCode)
|
||||
: Error("AWS authentication error: '%s' (%d)", aws_error_str(errorCode), errorCode)
|
||||
: CloneableError("AWS authentication error: '%s' (%d)", aws_error_str(errorCode), errorCode)
|
||||
, errorCode(errorCode)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#include "nix/store/build/goal.hh"
|
||||
#include "nix/store/build/worker.hh"
|
||||
#include "nix/store/globals.hh"
|
||||
#include "nix/store/worker-settings.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
TimedOut::TimedOut(time_t maxDuration)
|
||||
: BuildError(BuildResult::Failure::TimedOut, "timed out after %1% seconds", maxDuration)
|
||||
: CloneableError(BuildResult::Failure::TimedOut, "timed out after %1% seconds", maxDuration)
|
||||
, maxDuration(maxDuration)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -60,12 +60,12 @@ namespace {
|
||||
using curlSList = std::unique_ptr<::curl_slist, decltype([](::curl_slist * list) { ::curl_slist_free_all(list); })>;
|
||||
using curlMulti = std::unique_ptr<::CURLM, decltype([](::CURLM * multi) { ::curl_multi_cleanup(multi); })>;
|
||||
|
||||
struct curlMultiError : Error
|
||||
struct curlMultiError final : CloneableError<curlMultiError, Error>
|
||||
{
|
||||
::CURLMcode code;
|
||||
|
||||
curlMultiError(::CURLMcode code)
|
||||
: Error{"unexpected curl multi error: %s", ::curl_multi_strerror(code)}
|
||||
: CloneableError{"unexpected curl multi error: %s", ::curl_multi_strerror(code)}
|
||||
{
|
||||
assert(code != CURLM_OK);
|
||||
}
|
||||
@@ -1212,7 +1212,7 @@ void FileTransfer::download(
|
||||
template<typename... Args>
|
||||
FileTransferError::FileTransferError(
|
||||
FileTransfer::Error error, std::optional<std::string> response, const Args &... args)
|
||||
: Error(args...)
|
||||
: CloneableError(args...)
|
||||
, error(error)
|
||||
, response(response)
|
||||
{
|
||||
|
||||
@@ -34,12 +34,13 @@ struct AwsCredentials
|
||||
}
|
||||
};
|
||||
|
||||
class AwsAuthError : public Error
|
||||
class AwsAuthError final : public CloneableError<AwsAuthError, Error>
|
||||
{
|
||||
std::optional<int> errorCode;
|
||||
|
||||
public:
|
||||
using Error::Error;
|
||||
using CloneableError::CloneableError;
|
||||
|
||||
AwsAuthError(int errorCode);
|
||||
|
||||
std::optional<int> getErrorCode() const
|
||||
|
||||
@@ -58,7 +58,7 @@ enum struct BuildResultFailureStatus : uint8_t {
|
||||
* This is both an exception type (inherits from Error) and serves as
|
||||
* the failure variant in BuildResult::inner.
|
||||
*/
|
||||
struct BuildError : public Error
|
||||
struct BuildError : public CloneableError<BuildError, Error>
|
||||
{
|
||||
using Status = BuildResultFailureStatus;
|
||||
using enum Status;
|
||||
@@ -80,7 +80,7 @@ public:
|
||||
*/
|
||||
template<typename... Args>
|
||||
BuildError(Status status, const Args &... args)
|
||||
: Error(args...)
|
||||
: CloneableError(args...)
|
||||
, status{status}
|
||||
{
|
||||
}
|
||||
@@ -97,7 +97,7 @@ public:
|
||||
* Also used for deserialization.
|
||||
*/
|
||||
BuildError(Args args)
|
||||
: Error(std::move(args.msg))
|
||||
: CloneableError(std::move(args.msg))
|
||||
, status{args.status}
|
||||
, isNonDeterministic{args.isNonDeterministic}
|
||||
|
||||
@@ -108,7 +108,7 @@ public:
|
||||
* Default constructor for deserialization.
|
||||
*/
|
||||
BuildError()
|
||||
: Error("")
|
||||
: CloneableError("")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -20,14 +20,14 @@ namespace nix {
|
||||
* Denotes a build failure that stemmed from the builder exiting with a
|
||||
* failing exist status.
|
||||
*/
|
||||
struct BuilderFailureError : BuildError
|
||||
struct BuilderFailureError final : CloneableError<BuilderFailureError, BuildError>
|
||||
{
|
||||
int builderStatus;
|
||||
|
||||
std::string extraMsgAfter;
|
||||
|
||||
BuilderFailureError(BuildResult::Failure::Status status, int builderStatus, std::string extraMsgAfter)
|
||||
: BuildError{
|
||||
: CloneableError{
|
||||
status,
|
||||
/* No message for now, because the caller will make for
|
||||
us, with extra context */
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
namespace nix {
|
||||
|
||||
struct TimedOut : BuildError
|
||||
struct TimedOut final : CloneableError<TimedOut, BuildError>
|
||||
{
|
||||
time_t maxDuration;
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ struct Package
|
||||
}
|
||||
};
|
||||
|
||||
class BuildEnvFileConflictError : public Error
|
||||
class BuildEnvFileConflictError final : public CloneableError<BuildEnvFileConflictError, Error>
|
||||
{
|
||||
public:
|
||||
const Path fileA;
|
||||
@@ -30,7 +30,7 @@ public:
|
||||
int priority;
|
||||
|
||||
BuildEnvFileConflictError(const Path fileA, const Path fileB, int priority)
|
||||
: Error(
|
||||
: CloneableError(
|
||||
"Unable to build profile. There is a conflict for the following files:\n"
|
||||
"\n"
|
||||
" %1%\n"
|
||||
|
||||
@@ -403,7 +403,7 @@ ref<FileTransfer> getFileTransfer();
|
||||
*/
|
||||
ref<FileTransfer> makeFileTransfer(const FileTransferSettings & settings = fileTransferSettings);
|
||||
|
||||
class FileTransferError : public Error
|
||||
class FileTransferError final : public CloneableError<FileTransferError, Error>
|
||||
{
|
||||
public:
|
||||
FileTransfer::Error error;
|
||||
|
||||
@@ -146,7 +146,7 @@ struct RealisedPath
|
||||
auto operator<=>(const RealisedPath &) const = default;
|
||||
};
|
||||
|
||||
class MissingRealisation : public Error
|
||||
class MissingRealisation final : public CloneableError<MissingRealisation, Error>
|
||||
{
|
||||
public:
|
||||
MissingRealisation(DrvOutput & outputId)
|
||||
@@ -155,7 +155,7 @@ public:
|
||||
}
|
||||
|
||||
MissingRealisation(std::string_view drv, OutputName outputName)
|
||||
: Error(
|
||||
: CloneableError(
|
||||
"cannot operate on output '%s' of the "
|
||||
"unbuilt derivation '%s'",
|
||||
outputName,
|
||||
|
||||
@@ -166,7 +166,7 @@ struct SQLiteTxn
|
||||
~SQLiteTxn();
|
||||
};
|
||||
|
||||
struct SQLiteError : Error
|
||||
struct SQLiteError : CloneableError<SQLiteError, Error>
|
||||
{
|
||||
std::string path;
|
||||
std::string errMsg;
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace nix {
|
||||
|
||||
SQLiteError::SQLiteError(
|
||||
const char * path, const char * errMsg, int errNo, int extendedErrNo, int offset, HintFmt && hf)
|
||||
: Error("")
|
||||
: CloneableError("")
|
||||
, path(path)
|
||||
, errMsg(errMsg)
|
||||
, errNo(errNo)
|
||||
|
||||
@@ -18,11 +18,11 @@ static std::string parsePublicHostKey(std::string_view host, std::string_view ss
|
||||
}
|
||||
}
|
||||
|
||||
class InvalidSSHAuthority : public Error
|
||||
class InvalidSSHAuthority final : public CloneableError<InvalidSSHAuthority, Error>
|
||||
{
|
||||
public:
|
||||
InvalidSSHAuthority(const ParsedURL::Authority & authority, std::string_view reason)
|
||||
: Error("invalid SSH authority: '%s': %s", authority.to_string(), reason)
|
||||
: CloneableError("invalid SSH authority: '%s': %s", authority.to_string(), reason)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
@@ -55,10 +55,10 @@
|
||||
|
||||
namespace nix {
|
||||
|
||||
struct NotDeterministic : BuildError
|
||||
struct NotDeterministic final : CloneableError<NotDeterministic, BuildError>
|
||||
{
|
||||
NotDeterministic(auto &&... args)
|
||||
: BuildError(BuildResult::Failure::NotDeterministic, args...)
|
||||
: CloneableError(BuildResult::Failure::NotDeterministic, args...)
|
||||
{
|
||||
isNonDeterministic = true;
|
||||
}
|
||||
|
||||
@@ -378,7 +378,7 @@ std::set<ExperimentalFeature> parseFeatures(const StringSet & rawFeatures)
|
||||
}
|
||||
|
||||
MissingExperimentalFeature::MissingExperimentalFeature(ExperimentalFeature feature, std::string reason)
|
||||
: Error(
|
||||
: CloneableError(
|
||||
"experimental Nix feature '%1%' is disabled%2%; add '--extra-experimental-features %1%' to enable it",
|
||||
showExperimentalFeature(feature),
|
||||
Uncolored(optionalBracket(" (", reason, ")")))
|
||||
|
||||
@@ -226,13 +226,31 @@ public:
|
||||
{
|
||||
return err;
|
||||
};
|
||||
|
||||
[[noreturn]] virtual void throwClone() const = 0;
|
||||
};
|
||||
|
||||
#define MakeError(newClass, superClass) \
|
||||
class newClass : public superClass \
|
||||
{ \
|
||||
public: \
|
||||
using superClass::superClass; \
|
||||
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));
|
||||
}
|
||||
};
|
||||
|
||||
#define MakeError(newClass, superClass) \
|
||||
class newClass : public CloneableError<newClass, superClass> \
|
||||
{ \
|
||||
public: \
|
||||
using CloneableError<newClass, superClass>::CloneableError; \
|
||||
}
|
||||
|
||||
MakeError(Error, BaseError);
|
||||
@@ -244,21 +262,21 @@ MakeError(UnimplementedError, Error);
|
||||
* std::error_code. Use when you want to catch and check an error condition like
|
||||
* no_such_file_or_directory (ENOENT) without ifdefs.
|
||||
*/
|
||||
class SystemError : public Error
|
||||
class SystemError : public CloneableError<SystemError, Error>
|
||||
{
|
||||
std::error_code errorCode;
|
||||
|
||||
public:
|
||||
template<typename... Args>
|
||||
SystemError(std::errc posixErrNo, Args &&... args)
|
||||
: Error(std::forward<Args>(args)...)
|
||||
: CloneableError(std::forward<Args>(args)...)
|
||||
, errorCode(std::make_error_code(posixErrNo))
|
||||
{
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
SystemError(std::error_code errorCode, Args &&... args)
|
||||
: Error(std::forward<Args>(args)...)
|
||||
: CloneableError(std::forward<Args>(args)...)
|
||||
, errorCode(errorCode)
|
||||
{
|
||||
}
|
||||
@@ -290,7 +308,7 @@ public:
|
||||
* support is too WIP to justify the code churn, but if it is finished
|
||||
* then a better identifier becomes moe worth it.
|
||||
*/
|
||||
class SysError : public SystemError
|
||||
class SysError final : public CloneableError<SysError, SystemError>
|
||||
{
|
||||
public:
|
||||
int errNo;
|
||||
@@ -301,7 +319,7 @@ public:
|
||||
*/
|
||||
template<typename... Args>
|
||||
SysError(int errNo, const Args &... args)
|
||||
: SystemError(static_cast<std::errc>(errNo), "")
|
||||
: CloneableError(static_cast<std::errc>(errNo), "")
|
||||
, errNo(errNo)
|
||||
{
|
||||
auto hf = HintFmt(args...);
|
||||
@@ -369,7 +387,7 @@ namespace windows {
|
||||
* Unless you need to catch a specific error number, don't catch this in
|
||||
* portable code. Catch `SystemError` instead.
|
||||
*/
|
||||
class WinError : public SystemError
|
||||
class WinError : public CloneableError<WinError, SystemError>
|
||||
{
|
||||
public:
|
||||
DWORD lastError;
|
||||
@@ -381,7 +399,7 @@ public:
|
||||
*/
|
||||
template<typename... Args>
|
||||
WinError(DWORD lastError, const Args &... args)
|
||||
: SystemError(std::error_code(lastError, std::system_category()), "")
|
||||
: CloneableError(std::error_code(lastError, std::system_category()), "")
|
||||
, lastError(lastError)
|
||||
{
|
||||
auto hf = HintFmt(args...);
|
||||
|
||||
@@ -80,7 +80,7 @@ std::set<ExperimentalFeature> parseFeatures(const StringSet &);
|
||||
* An experimental feature was required for some (experimental)
|
||||
* operation, but was not enabled.
|
||||
*/
|
||||
class MissingExperimentalFeature : public Error
|
||||
class MissingExperimentalFeature final : public CloneableError<MissingExperimentalFeature, Error>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
|
||||
@@ -133,14 +133,14 @@ std::pair<int, std::string> runProgram(RunOptions && options);
|
||||
|
||||
void runProgram2(const RunOptions & options);
|
||||
|
||||
class ExecError : public Error
|
||||
class ExecError final : public CloneableError<ExecError, Error>
|
||||
{
|
||||
public:
|
||||
int status;
|
||||
|
||||
template<typename... Args>
|
||||
ExecError(int status, const Args &... args)
|
||||
: Error(args...)
|
||||
: CloneableError(args...)
|
||||
, status(status)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -231,19 +231,19 @@ ref<SourceAccessor> makeEmptySourceAccessor();
|
||||
*/
|
||||
MakeError(RestrictedPathError, Error);
|
||||
|
||||
struct SymlinkNotAllowed : public Error
|
||||
struct SymlinkNotAllowed final : public CloneableError<SymlinkNotAllowed, Error>
|
||||
{
|
||||
CanonPath path;
|
||||
|
||||
SymlinkNotAllowed(CanonPath path)
|
||||
: Error("relative path '%s' points to a symlink, which is not allowed", path.rel())
|
||||
: CloneableError("relative path '%s' points to a symlink, which is not allowed", path.rel())
|
||||
, path(std::move(path))
|
||||
{
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
SymlinkNotAllowed(CanonPath path, const std::string & fs, Args &&... args)
|
||||
: Error(fs, std::forward<Args>(args)...)
|
||||
: CloneableError(fs, std::forward<Args>(args)...)
|
||||
, path(std::move(path))
|
||||
{
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user