• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

STEllAR-GROUP / hpx / #882

31 Aug 2023 07:44PM UTC coverage: 41.798% (-44.7%) from 86.546%
#882

push

19442 of 46514 relevant lines covered (41.8%)

126375.38 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

33.33
/libs/core/errors/src/exception.cpp
1
//  Copyright (c) 2007-2025 Hartmut Kaiser
2
//  Copyright (c)      2011 Bryce Lelbach
3
//
4
//  SPDX-License-Identifier: BSL-1.0
5
//  Distributed under the Boost Software License, Version 1.0. (See accompanying
6
//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7

8
#include <hpx/config.hpp>
9
#include <hpx/assert.hpp>
10
#include <hpx/errors/define_error_info.hpp>
11
#include <hpx/errors/error.hpp>
12
#include <hpx/errors/error_code.hpp>
13
#include <hpx/errors/exception.hpp>
14
#include <hpx/errors/exception_fwd.hpp>
15
#include <hpx/errors/exception_info.hpp>
16
#include <hpx/errors/exception_list.hpp>
17
#include <hpx/modules/logging.hpp>
18

19
#if defined(HPX_WINDOWS)
20
#include <process.h>
21
#elif defined(HPX_HAVE_UNISTD_H)
22
#include <unistd.h>
23
#endif
24

25
#include <algorithm>
26
#include <cstdint>
27
#include <exception>
28
#include <memory>
29
#include <stdexcept>
30
#include <string>
31
#include <system_error>
32
#include <typeinfo>
33
#include <utility>
34

35
namespace hpx {
36

37
    ///////////////////////////////////////////////////////////////////////////
38
    /// Construct a hpx::exception from a \a hpx::error.
39
    ///
236✔
40
    /// \param e    The parameter \p e holds the hpx::error code the new
236✔
41
    ///             exception should encapsulate.
42
    exception::exception(hpx::error e)
43
      : std::system_error(make_error_code(e, throwmode::plain))
44
    {
236✔
45
        HPX_ASSERT((e >= hpx::error::success && e < hpx::error::last_error) ||
46
            (e & hpx::error::system_error_flag));
×
47
        if (e != hpx::error::success)
×
48
        {
49
            LERR_(error).format(    //-V1067
236✔
50
                "created exception: {}", this->exception::what());
51
        }
52
    }
×
53

×
54
    /// Construct a hpx::exception from a boost#system_error.
55
    exception::exception(std::system_error const& e)
×
56
      : std::system_error(e)
×
57
    {
×
58
        LERR_(error).format(    //-V1067
59
            "created exception: {}", this->exception::what());
60
    }
61

×
62
    /// Construct a hpx::exception from a boost#system#error_code (this is
×
63
    /// new for Boost V1.69).
64
    exception::exception(std::error_code const& e)
×
65
      : std::system_error(e)
×
66
    {
×
67
        LERR_(error).format(    //-V1067
68
            "created exception: {}", this->exception::what());
69
    }
70

71
    /// Construct a hpx::exception from a \a hpx::error and an error message.
72
    ///
73
    /// \param e      The parameter \p e holds the hpx::error code the new
74
    ///               exception should encapsulate.
75
    /// \param msg    The parameter \p msg holds the error message the new
76
    ///               exception should encapsulate.
77
    /// \param mode   The parameter \p mode specifies whether the returned
78
    ///               hpx::error_code belongs to the error category
79
    ///               \a hpx_category (if mode is \a throwmode::plain, this
×
80
    ///               is the default) or to the category \a hpx_category_rethrow
×
81
    ///               (if mode is \a throwmode::rethrow).
82
    exception::exception(hpx::error e, char const* msg, throwmode mode)
83
      : std::system_error(make_system_error_code(e, mode), msg)
84
    {
×
85
        HPX_ASSERT((e >= hpx::error::success && e < hpx::error::last_error) ||
86
            (e & hpx::error::system_error_flag));
×
87
        if (e != hpx::error::success)
×
88
        {
89
            LERR_(error).format(    //-V1067
×
90
                "created exception: {}", this->exception::what());
91
        }
92
    }
93

94
    /// Construct a hpx::exception from a \a hpx::error and an error message.
95
    ///
96
    /// \param e      The parameter \p e holds the hpx::error code the new
97
    ///               exception should encapsulate.
98
    /// \param msg    The parameter \p msg holds the error message the new
99
    ///               exception should encapsulate.
100
    /// \param mode   The parameter \p mode specifies whether the returned
101
    ///               hpx::error_code belongs to the error category
102
    ///               \a hpx_category (if mode is \a throwmode::plain, this is
5✔
103
    ///               the default) or to the category \a hpx_category_rethrow
5✔
104
    ///               (if mode is \a throwmode::rethrow).
105
    exception::exception(hpx::error e, std::string const& msg, throwmode mode)
106
      : std::system_error(make_system_error_code(e, mode), msg)
107
    {
5✔
108
        HPX_ASSERT((e >= hpx::error::success && e < hpx::error::last_error) ||
109
            (e & hpx::error::system_error_flag));
5✔
110
        if (e != hpx::error::success)
×
111
        {
112
            LERR_(error).format(    //-V1067
5✔
113
                "created exception: {}", this->exception::what());
114
        }
115
    }
116

117
    /// Destruct a hpx::exception
256✔
118
    ///
119
    /// \throws nothing
120
    exception::~exception() = default;
121

122
    /// The function \a get_error() returns the hpx::error code stored in the
123
    /// referenced instance of a hpx::exception. It returns the hpx::error code
124
    /// this exception instance was constructed from.
1✔
125
    ///
126
    /// \throws nothing
1✔
127
    error exception::get_error() const noexcept
128
    {
129
        return static_cast<error>(this->std::system_error::code().value());
130
    }
131

132
    /// The function \a get_error_code() returns a hpx::error_code which
133
    /// represents the same error condition as this hpx::exception instance.
134
    ///
135
    /// \param mode   The parameter \p mode specifies whether the returned
136
    ///               hpx::error_code belongs to the error category
137
    ///               \a hpx_category (if mode is \a throwmode::plain, this is
5✔
138
    ///               the default) or to the category \a hpx_category_rethrow
139
    ///               (if mode is \a throwmode::rethrow).
140
    error_code exception::get_error_code(throwmode mode) const noexcept
5✔
141
    {
142
        (void) mode;
143
        return {this->std::system_error::code().value(), *this};
144
    }
145

64✔
146
    bad_alloc_exception::bad_alloc_exception()
147
      : hpx::exception(hpx::error::out_of_memory)
64✔
148
    {
64✔
149
    }
150

151
    static custom_exception_info_handler_type custom_exception_info_handler;
152

64✔
153
    void set_custom_exception_info_handler(custom_exception_info_handler_type f)
154
    {
64✔
155
        custom_exception_info_handler = HPX_MOVE(f);
64✔
156
    }
157

158
    static pre_exception_handler_type pre_exception_handler;
159

160
    void set_pre_exception_handler(pre_exception_handler_type f)
161
    {
×
162
        pre_exception_handler = HPX_MOVE(f);
163
    }
164
}    // namespace hpx
165

166
namespace hpx::detail {
167

168
    template <typename Exception>
169
    std::exception_ptr construct_lightweight_exception(Exception const& e,
×
170
        std::string const& func, std::string const& file, long line)
171
    {
×
172
        // create a std::exception_ptr object encapsulating the Exception to
×
173
        // be thrown and annotate it with all the local information we have
×
174
        try
175
        {
×
176
            throw_with_info(e,
177
                std::move(
×
178
                    hpx::exception_info().set(hpx::detail::throw_function(func),
179
                        hpx::detail::throw_file(file),
180
                        hpx::detail::throw_line(line))));
181
        }
182
        catch (...)
183
        {
184
            return std::current_exception();
185
        }
186

×
187
        // need this return to silence a warning with icc
188
        HPX_ASSERT(false);    // -V779
189
        return std::exception_ptr();
190
    }
191

192
    template <typename Exception>
193
    std::exception_ptr construct_lightweight_exception(Exception const& e)
×
194
    {
195
        // create a std::exception_ptr object encapsulating the Exception to
×
196
        // be thrown and annotate it with all the local information we have
197
        try
×
198
        {
199
            hpx::throw_with_info(e);
200
        }
201
        catch (...)
202
        {
203
            return std::current_exception();
204
        }
205

206
        // need this return to silence a warning with icc
207
        HPX_ASSERT(false);    // -V779
208
        return std::exception_ptr();
209
    }
210

211
    template std::exception_ptr construct_lightweight_exception(
5✔
212
        hpx::thread_interrupted const&);
213
    template std::exception_ptr construct_lightweight_exception(
214
        hpx::exception_list const&);
215

5✔
216
    template <typename Exception>
217
    std::exception_ptr construct_custom_exception(Exception const& e,
×
218
        std::string const& func, std::string const& file, long line,
219
        std::string const& auxinfo)
220
    {
221
        if (!custom_exception_info_handler)
222
        {
223
            return construct_lightweight_exception(e, func, file, line);
224
        }
5✔
225

226
        // create a std::exception_ptr object encapsulating the Exception to
227
        // be thrown and annotate it with information provided by the hook
5✔
228
        try
229
        {
5✔
230
            throw_with_info(
231
                e, custom_exception_info_handler(func, file, line, auxinfo));
232
        }
233
        catch (...)
234
        {
235
            return std::current_exception();
236
        }
237

238
        // need this return to silence a warning with icc
239
        HPX_ASSERT(false);    // -V779
240
        return std::exception_ptr();
241
    }
242

243
    ///////////////////////////////////////////////////////////////////////////
244
    template <typename Exception>
245
    constexpr bool is_of_lightweight_hpx_category(Exception const&) noexcept
5✔
246
    {
247
        return false;
5✔
248
    }
249

250
    inline bool is_of_lightweight_hpx_category(hpx::exception const& e) noexcept
251
    {
×
252
        return e.get_error_code().category() == get_lightweight_hpx_category();
253
    }
×
254

255
    ///////////////////////////////////////////////////////////////////////////
256
    std::exception_ptr access_exception(error_code const& e)
257
    {
5✔
258
        return e.exception_;
259
    }
260

261
    template <typename Exception>
5✔
262
    std::exception_ptr get_exception(Exception const& e,
263
        std::string const& func, std::string const& file, long line,
×
264
        std::string const& auxinfo)
265
    {
266
        if (is_of_lightweight_hpx_category(e))
×
267
        {
268
            return construct_lightweight_exception(e, func, file, line);
269
        }
270

×
271
        return construct_custom_exception(e, func, file, line, auxinfo);
272
    }
273

×
274
    template <typename Exception>
275
    void throw_exception(Exception const& e, std::string const& func,
276
        std::string const& file, long line)
277
    {
278
        if (pre_exception_handler)
×
279
        {
280
            pre_exception_handler();
281
        }
282

283
        std::rethrow_exception(get_exception(e, func, file, line));
284
    }
285

286
    void throw_bad_alloc_exception([[maybe_unused]] char const* func,
287
        [[maybe_unused]] char const* file, [[maybe_unused]] long line)
288
    {
289
        if (pre_exception_handler)
290
        {
291
            pre_exception_handler();
292
        }
293

294
        throw hpx::bad_alloc_exception();
295
    }
296

297
    ///////////////////////////////////////////////////////////////////////////
298
    template std::exception_ptr get_exception(hpx::exception const&,
299
        std::string const&, std::string const&, long, std::string const&);
300
    template std::exception_ptr get_exception(std::system_error const&,
301
        std::string const&, std::string const&, long, std::string const&);
302
    template std::exception_ptr get_exception(std::exception const&,
303
        std::string const&, std::string const&, long, std::string const&);
304
    template std::exception_ptr get_exception(hpx::detail::std_exception const&,
305
        std::string const&, std::string const&, long, std::string const&);
306
    template std::exception_ptr get_exception(std::bad_exception const&,
307
        std::string const&, std::string const&, long, std::string const&);
308
    template std::exception_ptr get_exception(hpx::detail::bad_exception const&,
309
        std::string const&, std::string const&, long, std::string const&);
310
    template std::exception_ptr get_exception(std::bad_typeid const&,
311
        std::string const&, std::string const&, long, std::string const&);
312
    template std::exception_ptr get_exception(hpx::detail::bad_typeid const&,
313
        std::string const&, std::string const&, long, std::string const&);
314
    template std::exception_ptr get_exception(std::bad_cast const&,
315
        std::string const&, std::string const&, long, std::string const&);
316
    template std::exception_ptr get_exception(hpx::detail::bad_cast const&,
317
        std::string const&, std::string const&, long, std::string const&);
318
    template std::exception_ptr get_exception(std::bad_alloc const&,
319
        std::string const&, std::string const&, long, std::string const&);
320
    template std::exception_ptr get_exception(hpx::detail::bad_alloc const&,
321
        std::string const&, std::string const&, long, std::string const&);
322
    template std::exception_ptr get_exception(std::logic_error const&,
323
        std::string const&, std::string const&, long, std::string const&);
324
    template std::exception_ptr get_exception(std::runtime_error const&,
325
        std::string const&, std::string const&, long, std::string const&);
326
    template std::exception_ptr get_exception(std::out_of_range const&,
327
        std::string const&, std::string const&, long, std::string const&);
328
    template std::exception_ptr get_exception(std::invalid_argument const&,
329
        std::string const&, std::string const&, long, std::string const&);
330

331
    ///////////////////////////////////////////////////////////////////////////
332
    template void throw_exception(
333
        hpx::exception const&, std::string const&, std::string const&, long);
334
    template void throw_exception(
335
        std::system_error const&, std::string const&, std::string const&, long);
336
    template void throw_exception(
337
        std::exception const&, std::string const&, std::string const&, long);
338
    template void throw_exception(hpx::detail::std_exception const&,
339
        std::string const&, std::string const&, long);
340
    template void throw_exception(std::bad_exception const&, std::string const&,
341
        std::string const&, long);
342
    template void throw_exception(hpx::detail::bad_exception const&,
343
        std::string const&, std::string const&, long);
344
    template void throw_exception(
345
        std::bad_typeid const&, std::string const&, std::string const&, long);
346
    template void throw_exception(hpx::detail::bad_typeid const&,
347
        std::string const&, std::string const&, long);
348
    template void throw_exception(
349
        std::bad_cast const&, std::string const&, std::string const&, long);
350
    template void throw_exception(hpx::detail::bad_cast const&,
351
        std::string const&, std::string const&, long);
352
    template void throw_exception(
353
        std::bad_alloc const&, std::string const&, std::string const&, long);
354
    template void throw_exception(hpx::detail::bad_alloc const&,
355
        std::string const&, std::string const&, long);
356
    template void throw_exception(
357
        std::logic_error const&, std::string const&, std::string const&, long);
358
    template void throw_exception(std::runtime_error const&, std::string const&,
359
        std::string const&, long);
360
    template void throw_exception(
361
        std::out_of_range const&, std::string const&, std::string const&, long);
362
    template void throw_exception(std::invalid_argument const&,
363
        std::string const&, std::string const&, long);
364
}    // namespace hpx::detail
365

366
///////////////////////////////////////////////////////////////////////////////
367
namespace hpx {
368

369
    ///////////////////////////////////////////////////////////////////////////
370
    /// Return the error message.
371
    std::string get_error_what(hpx::exception_info const& xi)
372
    {
373
        // Try a cast to std::exception - this should handle boost.system
374
        // error codes in addition to the standard library exceptions.
375
        auto const* se = dynamic_cast<std::exception const*>(&xi);
376
        return se ? se->what() : std::string("<unknown>");
377
    }
378

×
379
    std::string get_error_what(std::exception_ptr const& e)
380
    {
381
        try
382
        {
×
383
            std::rethrow_exception(e);
×
384
        }
385
        catch (hpx::thread_interrupted const&)
386
        {
×
387
            return "thread_interrupted";
388
        }
389
        catch (std::exception const& ex)
390
        {
×
391
            return get_error_what(ex);
392
        }
×
393
        catch (...)
394
        {
×
395
            return "<unknown>";
×
396
        }
×
397
    }
398

399
    ///////////////////////////////////////////////////////////////////////////
×
400
    error get_error(hpx::exception const& e)
×
401
    {
402
        return static_cast<hpx::error>(e.get_error());
×
403
    }
×
404

405
    error get_error(hpx::error_code const& e)
406
    {
407
        return static_cast<hpx::error>(e.value());
×
408
    }
409

×
410
    error get_error(std::exception_ptr const& e)
411
    {
412
        try
×
413
        {
414
            std::rethrow_exception(e);
×
415
        }
416
        catch (hpx::thread_interrupted const&)
417
        {
1✔
418
            return hpx::error::thread_cancelled;
419
        }
420
        catch (hpx::exception const& he)
421
        {
1✔
422
            return he.get_error();
423
        }
1✔
424
        catch (std::system_error const& se)
425
        {
426
            int code = se.code().value();
×
427
            if (code < hpx::error::success || code >= hpx::error::last_error)
1✔
428
            {
429
                code |= hpx::error::system_error_flag;
1✔
430
            }
1✔
431
            return static_cast<hpx::error>(code);
×
432
        }
433
        catch (...)
434
        {
×
435
            return hpx::error::unknown_error;
436
        }
437
    }
438

×
439
    /// Return the function name from which the exception was thrown.
×
440
    std::string get_error_function_name(hpx::exception_info const& xi)
×
441
    {
442
        if (std::string const* function = xi.get<hpx::detail::throw_function>())
443
            return *function;
×
444

445
        return {};
446
    }
447

×
448
    /// Return the (source code) file name of the function from which the
449
    /// exception was thrown.
450
    std::string get_error_file_name(hpx::exception_info const& xi)
×
451
    {
452
        if (std::string const* file = xi.get<hpx::detail::throw_file>())
453
            return *file;
454

455
        return "<unknown>";
456
    }
457

458
    /// Return the line number in the (source code) file of the function from
×
459
    /// which the exception was thrown.
460
    long get_error_line_number(hpx::exception_info const& xi)
461
    {
×
462
        if (long const* line = xi.get<hpx::detail::throw_line>())
463
            return *line;
464

×
465
        return -1;
466
    }
467

468
}    // namespace hpx
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc