Horizon
exceptions.hpp
1 #pragma once
2 
3 #include <exception> // exception
4 #include <stdexcept> // runtime_error
5 #include <string> // to_string
6 #include <vector> // vector
7 
8 #include <nlohmann/detail/value_t.hpp>
9 #include <nlohmann/detail/string_escape.hpp>
10 #include <nlohmann/detail/input/position_t.hpp>
11 #include <nlohmann/detail/macro_scope.hpp>
12 
13 namespace nlohmann
14 {
15 namespace detail
16 {
18 // exceptions //
20 
49 class exception : public std::exception
50 {
51  public:
53  const char* what() const noexcept override
54  {
55  return m.what();
56  }
57 
59  const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
60 
61  protected:
62  JSON_HEDLEY_NON_NULL(3)
63  exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
64 
65  static std::string name(const std::string& ename, int id_)
66  {
67  return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
68  }
69 
70  template<typename BasicJsonType>
71  static std::string diagnostics(const BasicJsonType& leaf_element)
72  {
73 #if JSON_DIAGNOSTICS
74  std::vector<std::string> tokens;
75  for (const auto* current = &leaf_element; current->m_parent != nullptr; current = current->m_parent)
76  {
77  switch (current->m_parent->type())
78  {
79  case value_t::array:
80  {
81  for (std::size_t i = 0; i < current->m_parent->m_value.array->size(); ++i)
82  {
83  if (&current->m_parent->m_value.array->operator[](i) == current)
84  {
85  tokens.emplace_back(std::to_string(i));
86  break;
87  }
88  }
89  break;
90  }
91 
92  case value_t::object:
93  {
94  for (const auto& element : *current->m_parent->m_value.object)
95  {
96  if (&element.second == current)
97  {
98  tokens.emplace_back(element.first.c_str());
99  break;
100  }
101  }
102  break;
103  }
104 
105  case value_t::null: // LCOV_EXCL_LINE
106  case value_t::string: // LCOV_EXCL_LINE
107  case value_t::boolean: // LCOV_EXCL_LINE
108  case value_t::number_integer: // LCOV_EXCL_LINE
109  case value_t::number_unsigned: // LCOV_EXCL_LINE
110  case value_t::number_float: // LCOV_EXCL_LINE
111  case value_t::binary: // LCOV_EXCL_LINE
112  case value_t::discarded: // LCOV_EXCL_LINE
113  default: // LCOV_EXCL_LINE
114  break; // LCOV_EXCL_LINE
115  }
116  }
117 
118  if (tokens.empty())
119  {
120  return "";
121  }
122 
123  return "(" + std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},
124  [](const std::string & a, const std::string & b)
125  {
126  return a + "/" + detail::escape(b);
127  }) + ") ";
128 #else
129  static_cast<void>(leaf_element);
130  return "";
131 #endif
132  }
133 
134  private:
136  std::runtime_error m;
137 };
138 
184 class parse_error : public exception
185 {
186  public:
196  template<typename BasicJsonType>
197  static parse_error create(int id_, const position_t& pos, const std::string& what_arg, const BasicJsonType& context)
198  {
199  std::string w = exception::name("parse_error", id_) + "parse error" +
200  position_string(pos) + ": " + exception::diagnostics(context) + what_arg;
201  return parse_error(id_, pos.chars_read_total, w.c_str());
202  }
203 
204  template<typename BasicJsonType>
205  static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, const BasicJsonType& context)
206  {
207  std::string w = exception::name("parse_error", id_) + "parse error" +
208  (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") +
209  ": " + exception::diagnostics(context) + what_arg;
210  return parse_error(id_, byte_, w.c_str());
211  }
212 
222  const std::size_t byte;
223 
224  private:
225  parse_error(int id_, std::size_t byte_, const char* what_arg)
226  : exception(id_, what_arg), byte(byte_) {}
227 
228  static std::string position_string(const position_t& pos)
229  {
230  return " at line " + std::to_string(pos.lines_read + 1) +
231  ", column " + std::to_string(pos.chars_read_current_line);
232  }
233 };
234 
273 {
274  public:
275  template<typename BasicJsonType>
276  static invalid_iterator create(int id_, const std::string& what_arg, const BasicJsonType& context)
277  {
278  std::string w = exception::name("invalid_iterator", id_) + exception::diagnostics(context) + what_arg;
279  return invalid_iterator(id_, w.c_str());
280  }
281 
282  private:
283  JSON_HEDLEY_NON_NULL(3)
284  invalid_iterator(int id_, const char* what_arg)
285  : exception(id_, what_arg) {}
286 };
287 
327 class type_error : public exception
328 {
329  public:
330  template<typename BasicJsonType>
331  static type_error create(int id_, const std::string& what_arg, const BasicJsonType& context)
332  {
333  std::string w = exception::name("type_error", id_) + exception::diagnostics(context) + what_arg;
334  return type_error(id_, w.c_str());
335  }
336 
337  private:
338  JSON_HEDLEY_NON_NULL(3)
339  type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
340 };
341 
375 class out_of_range : public exception
376 {
377  public:
378  template<typename BasicJsonType>
379  static out_of_range create(int id_, const std::string& what_arg, const BasicJsonType& context)
380  {
381  std::string w = exception::name("out_of_range", id_) + exception::diagnostics(context) + what_arg;
382  return out_of_range(id_, w.c_str());
383  }
384 
385  private:
386  JSON_HEDLEY_NON_NULL(3)
387  out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
388 };
389 
414 class other_error : public exception
415 {
416  public:
417  template<typename BasicJsonType>
418  static other_error create(int id_, const std::string& what_arg, const BasicJsonType& context)
419  {
420  std::string w = exception::name("other_error", id_) + exception::diagnostics(context) + what_arg;
421  return other_error(id_, w.c_str());
422  }
423 
424  private:
425  JSON_HEDLEY_NON_NULL(3)
426  other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
427 };
428 } // namespace detail
429 } // namespace nlohmann
general exception of the basic_json class
Definition: exceptions.hpp:50
const char * what() const noexcept override
returns the explanatory string
Definition: exceptions.hpp:53
const int id
the id of the exception
Definition: exceptions.hpp:59
exception indicating errors with iterators
Definition: exceptions.hpp:273
exception indicating other library errors
Definition: exceptions.hpp:415
exception indicating access out of the defined range
Definition: exceptions.hpp:376
exception indicating a parse error
Definition: exceptions.hpp:185
const std::size_t byte
byte index of the parse error
Definition: exceptions.hpp:222
static parse_error create(int id_, const position_t &pos, const std::string &what_arg, const BasicJsonType &context)
create a parse error exception
Definition: exceptions.hpp:197
exception indicating executing a member function with a wrong type
Definition: exceptions.hpp:328
@ number_integer
number value (signed integer)
@ discarded
discarded by the parser callback function
@ binary
binary array (ordered collection of bytes)
@ object
object (unordered set of name/value pairs)
@ number_float
number value (floating-point)
@ number_unsigned
number value (unsigned integer)
@ array
array (ordered collection of values)
namespace for Niels Lohmann
Definition: adl_serializer.hpp:12
struct to capture the start position of the current token
Definition: position_t.hpp:11
std::size_t lines_read
the number of lines read
Definition: position_t.hpp:17
std::size_t chars_read_current_line
the number of characters read in the current line
Definition: position_t.hpp:15
std::size_t chars_read_total
the total number of characters read
Definition: position_t.hpp:13