Nix  2.93.0-dev
Lix: A modern, delicious implementation of the Nix package manager; unstable internal interfaces
Loading...
Searching...
No Matches
error.hh
Go to the documentation of this file.
1#pragma once
18#include "lix/libutil/json-fwd.hh"
20#include "lix/libutil/fmt.hh"
21
22#include <cstring>
23#include <list>
24#include <memory>
25#include <optional>
26
27#include <sys/types.h>
28#include <sys/stat.h>
29#include <fcntl.h>
30#include <system_error>
31#include <type_traits>
32
33namespace nix {
34
35
36typedef enum {
37 lvlError = 0,
38 lvlWarn,
39 lvlNotice,
40 lvlInfo,
41 lvlTalkative,
42 lvlChatty,
43 lvlDebug,
44 lvlVomit
45} Verbosity;
46
47template<>
48struct json::is_integral_enum<Verbosity> : std::true_type {};
49
50Verbosity verbosityFromIntClamped(int val);
51
56 std::optional<std::string> prevLineOfCode;
57 std::optional<std::string> errLineOfCode;
58 std::optional<std::string> nextLineOfCode;
59};
60
61struct Pos;
62
63void printCodeLines(std::ostream & out,
64 const std::string & prefix,
65 const Pos & errPos,
66 const LinesOfCode & loc);
67
68enum struct TracePrint {
72 Default,
76 Always,
77};
78
79enum struct TraceSize {
83};
84
85struct Trace {
86 std::shared_ptr<Pos> pos;
87 HintFmt hint;
88 TracePrint print = TracePrint::Default;
89};
90
91inline bool operator<(const Trace& lhs, const Trace& rhs);
92inline bool operator> (const Trace& lhs, const Trace& rhs);
93inline bool operator<=(const Trace& lhs, const Trace& rhs);
94inline bool operator>=(const Trace& lhs, const Trace& rhs);
95
96struct ErrorInfo {
97 Verbosity level = Verbosity::lvlError;
98 HintFmt msg;
99 std::shared_ptr<Pos> pos;
100 std::list<Trace> traces = {};
101
105 unsigned int status = 1;
106
107 Suggestions suggestions = {};
108
109 static std::optional<std::string> programName;
110};
111
112std::ostream & showErrorInfo(std::ostream & out, const ErrorInfo & einfo, bool showTrace);
113
118class BaseError : public std::exception
119{
120protected:
121 mutable ErrorInfo err;
122
126 mutable std::optional<std::string> what_;
130 const std::string & calcWhat() const;
131
132public:
133 BaseError(const BaseError &) = default;
134
135 BaseError & operator=(BaseError const & rhs) = default;
136
137 template<typename... Args>
138 BaseError(unsigned int status, const Args & ... args)
139 : err { .level = lvlError, .msg = HintFmt(args...), .status = status }
140 { }
141
142 template<typename... Args>
143 explicit BaseError(const std::string & fs, const Args & ... args)
144 : err { .level = lvlError, .msg = HintFmt(fs, args...) }
145 { }
146
147 template<typename... Args>
148 BaseError(const Suggestions & sug, const Args & ... args)
149 : err { .level = lvlError, .msg = HintFmt(args...), .suggestions = sug }
150 { }
151
152 BaseError(HintFmt hint)
153 : err { .level = lvlError, .msg = hint }
154 { }
155
156 BaseError(ErrorInfo && e)
157 : err(std::move(e))
158 { }
159
160 BaseError(const ErrorInfo & e)
161 : err(e)
162 { }
163
164 const char * what() const noexcept override { return calcWhat().c_str(); }
165 const std::string & msg() const { return calcWhat(); }
166 const ErrorInfo & info() const { calcWhat(); return err; }
167
168 void withExitStatus(unsigned int status)
169 {
170 err.status = status;
171 }
172
173 void atPos(std::shared_ptr<Pos> pos) {
174 err.pos = pos;
175 }
176
177 void pushTrace(Trace trace)
178 {
179 err.traces.push_front(trace);
180 }
181
182 template<typename... Args>
183 void addTrace(std::shared_ptr<Pos> && e, std::string_view fs, const Args & ... args)
184 {
185 addTrace(std::move(e), HintFmt(std::string(fs), args...));
186 }
187
188 void addTrace(std::shared_ptr<Pos> && e, HintFmt hint, TracePrint print = TracePrint::Default);
189
190 bool hasTrace() const { return !err.traces.empty(); }
191
192 const ErrorInfo & info() { return err; };
193};
194
195#define MakeError(newClass, superClass) \
196 /* NOLINTNEXTLINE(bugprone-macro-parentheses) */ \
197 class newClass : public superClass \
198 { \
199 public: \
200 using superClass::superClass; \
201 }
202
203MakeError(Error, BaseError);
204MakeError(UsageError, Error);
205MakeError(UnimplementedError, Error);
206
207class SysError : public Error
208{
209public:
210 int errNo;
211
212 template<typename... Args>
213 SysError(int errNo_, const Args & ... args)
214 : Error("")
215 {
216 errNo = errNo_;
217 auto hf = HintFmt(args...);
218 err.msg = HintFmt("%1%: %2%", Uncolored(hf.str()), strerror(errNo));
219 }
220
221 template<typename... Args>
222 SysError(std::error_code ec, const Args & ... args)
223 : Error("")
224 {
225 errNo = ec.value();
226 auto hf = HintFmt(args...);
227 err.msg = HintFmt("%1%: %2%", Uncolored(hf.str()), ec.message());
228 }
229
230 template<typename... Args>
231 SysError(const Args & ... args)
232 : SysError(errno, args ...)
233 {
234 }
235};
236
247void ignoreExceptionInDestructor(Verbosity lvl = lvlError);
248
256void ignoreExceptionExceptInterrupt(Verbosity lvl = lvlError);
257
258}
Definition args.hh:31
Definition error.hh:119
const std::string & calcWhat() const
Definition error.cc:22
std::optional< std::string > what_
Definition error.hh:126
Definition fmt.hh:157
Definition suggestions.hh:29
Definition error.hh:208
TracePrint
Definition error.hh:68
Definition error.hh:96
unsigned int status
Definition error.hh:105
Definition error.hh:55
Definition position.hh:19
Definition error.hh:85
Definition fmt.hh:44
Definition json-fwd.hh:21