Spicy
exception.h
1 // Copyright (c) 2020-2021 by the Zeek Project. See LICENSE for details.
2 
3 #pragma once
4 
5 #include <iostream>
6 #include <stdexcept>
7 #include <string>
8 #include <utility>
9 #include <vector>
10 
11 #include <hilti/rt/backtrace.h>
12 #include <hilti/rt/extension-points.h>
13 #include <hilti/rt/fmt.h>
14 
15 namespace hilti::rt {
16 
21 class Exception : public std::runtime_error {
22 public:
26  Exception(const std::string& desc);
27 
32  Exception(std::string_view desc, std::string_view location);
33 
34  Exception() : std::runtime_error("<no error>"){};
35  Exception(const Exception&) = default;
36  Exception(Exception&&) noexcept = default;
37  Exception& operator=(const Exception&) = default;
38  Exception& operator=(Exception&&) noexcept = default;
39 
40  // Empty, but required to make exception handling work between library
41  // and host application. See:
42  // http://www.toptip.ca/2012/06/c-exceptions-thrown-from-shared-library.html
43  virtual ~Exception();
44 
46  auto description() const { return _description; }
47 
49  auto location() const { return _location; }
50 
55  auto backtrace() const { return _backtrace.backtrace(); }
56 
57 private:
58  Exception(const std::string& what, std::string_view desc, std::string_view location);
59 
60  std::string _description;
61  std::string _location;
62  Backtrace _backtrace;
63 };
64 
65 #define HILTI_EXCEPTION(name, base) \
66  class name : public ::hilti::rt::base { \
67  public: \
68  using ::hilti::rt::base::base; \
69  virtual ~name(); /* required to create vtable, see hilti::rt::Exception */ \
70  };
71 
72 #define HILTI_EXCEPTION_NS(name, ns, base) \
73  class name : public ns::base { \
74  public: \
75  using ns::base::base; \
76  virtual ~name(); /* required to create vtable, see hilti::rt::Exception */ \
77  };
78 
79 #define HILTI_EXCEPTION_IMPL(name) name::name::~name() = default;
80 
82 HILTI_EXCEPTION(RuntimeError, Exception)
83 
84 
85 HILTI_EXCEPTION(UserException, Exception)
86 
87 
88 HILTI_EXCEPTION(AssertionFailure, RuntimeError)
89 
90 /*
91  * Exception triggered y the ".?" operator to signal to host applications that
92  * a struct attribbute isn't set.
93  */
94 HILTI_EXCEPTION(AttributeNotSet, Exception)
95 
96 
99 HILTI_EXCEPTION(DivisionByZero, RuntimeError)
100 
101 
102 HILTI_EXCEPTION(EnvironmentError, Exception)
103 
104 
105 HILTI_EXCEPTION(ExpiredReference, RuntimeError)
106 
107 
110 HILTI_EXCEPTION(Frozen, RuntimeError)
111 
112 
113 HILTI_EXCEPTION(IllegalReference, RuntimeError)
114 
115 
116 HILTI_EXCEPTION(IndexError, RuntimeError)
117 
118 
119 HILTI_EXCEPTION(InvalidArgument, RuntimeError);
120 
122 HILTI_EXCEPTION(InvalidIterator, RuntimeError)
123 
124 
125 HILTI_EXCEPTION(InvalidValue, RuntimeError);
126 
128 HILTI_EXCEPTION(MatchStateReuse, RuntimeError)
129 
130 
131 HILTI_EXCEPTION(NotSupported, RuntimeError)
132 
133 
134 HILTI_EXCEPTION(NullReference, RuntimeError)
135 
136 
137 HILTI_EXCEPTION(OutOfRange, RuntimeError)
138 
139 
142 HILTI_EXCEPTION(Overflow, RuntimeError)
143 
144 
145 HILTI_EXCEPTION(PatternError, RuntimeError)
146 
147 
148 HILTI_EXCEPTION(UnhandledSwitchCase, RuntimeError)
149 
150 
151 HILTI_EXCEPTION(UnicodeError, RuntimeError)
152 
153 
156 HILTI_EXCEPTION(UnsetOptional, RuntimeError)
157 
158 
161 HILTI_EXCEPTION(UnsetUnionMember, RuntimeError)
162 
163 
166 HILTI_EXCEPTION(StackSizeExceeded, RuntimeError)
167 
168 
169 class FormattingError : public RuntimeError {
170 public:
171  FormattingError(std::string desc) : RuntimeError(_sanitize(std::move(desc))) {}
172 
173 private:
174  std::string _sanitize(std::string desc) {
175  if ( auto pos = desc.find("tinyformat: "); pos != std::string::npos )
176  desc.erase(pos, 12);
177 
178  return desc;
179  }
180 };
181 
190 class WouldBlock : public std::runtime_error {
191 public:
192  using std::runtime_error::runtime_error;
193 
198  WouldBlock(const std::string& desc, const std::string& location);
199 };
200 
201 namespace exception {
202 
203 // Disables `Configuration::abort_on_exception` during its lifetime.
205 public:
208 
211  DisableAbortOnExceptions& operator=(const DisableAbortOnExceptions&) = delete;
212  DisableAbortOnExceptions& operator=(DisableAbortOnExceptions&&) noexcept = delete;
213 };
214 
216 void printUncaught(const Exception& e);
217 
219 void printUncaught(const Exception& e, std::ostream& out);
220 } // namespace exception
221 
222 namespace detail::adl {
223 inline std::string to_string(const Exception& e, adl::tag /*unused*/) { return fmt("<exception: %s>", e.what()); }
224 inline std::string to_string(const WouldBlock& e, adl::tag /*unused*/) { return fmt("<exception: %s>", e.what()); }
225 } // namespace detail::adl
226 
227 } // namespace hilti::rt
auto backtrace() const
Definition: exception.h:55
std::string to_string(T &&x)
Definition: extension-points.h:26
Definition: exception.h:190
Definition: any.h:7
auto description() const
Definition: exception.h:46
Definition: exception.h:169
Definition: backtrace.h:14
auto location() const
Definition: exception.h:49
Definition: exception.h:21
Definition: location.h:93
std::string fmt(const char *fmt, const Args &... args)
Definition: fmt.h:13
HILTI_EXCEPTION(InvalidArgument, RuntimeError)