Coverage Report

Created: 2025-12-20 06:36

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/jsoncons/include/jsoncons/json_exception.hpp
Line
Count
Source
1
// Copyright 2013-2025 Daniel Parker
2
// Distributed under the Boost license, Version 1.0.
3
// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
4
5
// See https://github.com/danielaparker/jsoncons for latest version
6
7
#ifndef JSONCONS_JSON_EXCEPTION_HPP
8
#define JSONCONS_JSON_EXCEPTION_HPP
9
10
#include <cstddef>
11
#include <exception>
12
#include <stdexcept>
13
#include <string> // std::string
14
#include <system_error> // std::error_code
15
16
#include <jsoncons/config/compiler_support.hpp>
17
#include <jsoncons/utility/more_type_traits.hpp>
18
#include <jsoncons/utility/unicode_traits.hpp> // unicode_traits::convert
19
20
namespace jsoncons {
21
22
    // json_exception
23
24
    class json_exception
25
    {
26
    public:
27
337
        virtual ~json_exception() = default;
28
        virtual const char* what() const noexcept = 0;
29
    };
30
31
    // json_runtime_error
32
33
    template <typename Base,typename Enable = void>
34
    class json_runtime_error
35
    {
36
    };
37
38
    template <typename Base>
39
    class json_runtime_error<Base,
40
                             typename std::enable_if<std::is_convertible<Base*,std::exception*>::value &&
41
                                                     ext_traits::is_constructible_from_string<Base>::value>::type> 
42
        : public Base, public virtual json_exception
43
    {
44
    public:
45
        json_runtime_error(const std::string& s) noexcept
46
0
            : Base(s)
47
0
        {
48
0
        }
49
        ~json_runtime_error() noexcept
50
0
        {
51
0
        }
52
        const char* what() const noexcept override
53
0
        {
54
0
            return Base::what();
55
0
        }
56
    };
57
58
    class bad_cast : public std::runtime_error
59
    {
60
        using std::runtime_error::runtime_error;
61
    };
62
63
    class key_not_found : public std::out_of_range, public virtual json_exception
64
    {
65
        std::string name_;
66
        mutable std::string what_;
67
    public:
68
        template <typename CharT>
69
        explicit key_not_found(const CharT* key, std::size_t length) noexcept
70
            : std::out_of_range("Key not found")
71
        {
72
            JSONCONS_TRY
73
            {
74
                unicode_traits::convert(key, length, name_,
75
                                 unicode_traits::conv_flags::strict);
76
            }
77
            JSONCONS_CATCH(...)
78
            {
79
            }
80
        }
81
82
        virtual ~key_not_found() noexcept
83
0
        {
84
0
        }
85
86
        const char* what() const noexcept override
87
0
        {
88
0
            if (what_.empty())
89
0
            {
90
0
                JSONCONS_TRY
91
0
                {
92
0
                    what_.append(std::out_of_range::what());
93
0
                    what_.append(": '");
94
0
                    what_.append(name_);
95
0
                    what_.append("'");
96
0
                    return what_.c_str();
97
0
                }
98
0
                JSONCONS_CATCH(...)
99
0
                {
100
0
                    return std::out_of_range::what();
101
0
                }
102
0
            }
103
0
            else
104
0
            {
105
0
                return what_.c_str();
106
0
            }
107
0
        }
108
    };
109
110
    class not_an_object : public std::runtime_error, public virtual json_exception
111
    {
112
        std::string name_;
113
        mutable std::string what_;
114
    public:
115
        template <typename CharT>
116
        explicit not_an_object(const CharT* key, std::size_t length) noexcept
117
            : std::runtime_error("Attempting to access a member of a value that is not an object")
118
        {
119
            JSONCONS_TRY
120
            {
121
                unicode_traits::convert(key, length, name_,
122
                                 unicode_traits::conv_flags::strict);
123
            }
124
            JSONCONS_CATCH(...)
125
            {
126
            }
127
        }
128
129
        virtual ~not_an_object() noexcept
130
0
        {
131
0
        }
132
        const char* what() const noexcept override
133
0
        {
134
0
            if (what_.empty())
135
0
            {
136
0
                JSONCONS_TRY
137
0
                {
138
0
                    what_.append(std::runtime_error::what());
139
0
                    what_.append(": '");
140
0
                    what_.append(name_);
141
0
                    what_.append("'");
142
0
                    return what_.c_str();
143
0
                }
144
0
                JSONCONS_CATCH(...)
145
0
                {
146
0
                    return std::runtime_error::what();
147
0
                }
148
0
            }
149
0
            else
150
0
            {
151
0
                return what_.c_str();
152
0
            }
153
0
        }
154
    };
155
156
    class ser_error : public std::exception, public virtual json_exception
157
    {
158
        std::string err_;
159
        std::error_code ec_;
160
        std::size_t line_{0};
161
        std::size_t column_{0};
162
    public:
163
        ser_error(std::error_code ec)
164
            : ec_(ec)
165
0
        {
166
0
            err_ = to_what_arg(ec); 
167
0
        }
168
        ser_error(std::error_code ec, const std::string& what_arg)
169
            : ec_(ec)
170
0
        {
171
0
            err_ = to_what_arg(ec, what_arg.c_str()); 
172
0
        }
173
        ser_error(std::error_code ec, const char* what_arg)
174
            : ec_(ec)
175
0
        {
176
0
            err_ = to_what_arg(ec, what_arg); 
177
0
        }
178
        ser_error(std::error_code ec, std::size_t position)
179
            : ec_(ec), column_(position)
180
0
        {
181
0
            err_ = to_what_arg(ec, "", 0, position); 
182
0
        }
183
        ser_error(std::error_code ec, const std::string& what_arg, std::size_t position)
184
            : ec_(ec), column_(position)
185
0
        {
186
0
            err_ = to_what_arg(ec, what_arg.c_str(), 0, position); 
187
0
        }
188
        ser_error(std::error_code ec, const char* what_arg, std::size_t position)
189
            : ec_(ec), column_(position)
190
0
        {
191
0
            err_ = to_what_arg(ec, what_arg, 0, position); 
192
0
        }
193
        ser_error(std::error_code ec, std::size_t line, std::size_t column)
194
337
            : ec_(ec), line_(line), column_(column)
195
337
        {
196
337
            err_ = to_what_arg(ec, "", line, column); 
197
337
        }
198
        ser_error(std::error_code ec, const std::string& what_arg, std::size_t line, std::size_t column)
199
            : ec_(ec), line_(line), column_(column)
200
0
        {
201
0
            err_ = to_what_arg(ec, what_arg.c_str(), line, column); 
202
0
        }
203
        ser_error(std::error_code ec, const char* what_arg, std::size_t line, std::size_t column)
204
            : ec_(ec), line_(line), column_(column)
205
0
        {
206
0
            err_ = to_what_arg(ec, what_arg, line, column); 
207
0
        }
208
        ser_error(const ser_error& other) = default;
209
210
        ser_error& operator=(const ser_error& other) = default;
211
212
        const char* what() const noexcept final
213
0
        {
214
0
            return err_.c_str();
215
0
        }
216
        
217
        std::error_code code() const
218
0
        {
219
0
            return ec_;
220
0
        }
221
222
        std::size_t line() const noexcept
223
0
        {
224
0
            return line_;
225
0
        }
226
227
        std::size_t column() const noexcept
228
0
        {
229
0
            return column_;
230
0
        }
231
    private:
232
        static std::string to_what_arg(std::error_code ec, const char* s="", std::size_t line=0, std::size_t column=0)
233
337
        {
234
337
            std::string what_arg(s);
235
337
            if (!what_arg.empty())
236
0
            {
237
0
                what_arg.append(": ");
238
0
            }
239
337
            what_arg.append(ec.message());
240
337
            if (line != 0 && column != 0)
241
0
            {
242
0
                what_arg.append(" at line ");
243
0
                what_arg.append(std::to_string(line));
244
0
                what_arg.append(" and column ");
245
0
                what_arg.append(std::to_string(column));
246
0
            }
247
337
            else if (column != 0)
248
337
            {
249
337
                what_arg.append(" at position ");
250
337
                what_arg.append(std::to_string(column));
251
337
            }
252
337
            return what_arg; 
253
337
        }
254
    };
255
256
} // namespace jsoncons
257
258
#endif // JSONCONS_JSON_EXCEPTION_HPP