• 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

9.68
/libs/core/serialization/src/exception_ptr.cpp
1
//  Copyright (c)      2020 ETH Zurich
2
//  Copyright (c) 2007-2025 Hartmut Kaiser
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/serialization/config/defines.hpp>
9
#include <hpx/assert.hpp>
10
#include <hpx/modules/errors.hpp>
11
#include <hpx/serialization/exception_ptr.hpp>
12
#include <hpx/serialization/serialize.hpp>
13

14
#if ASIO_HAS_BOOST_THROW_EXCEPTION != 0
15
#include <boost/exception/diagnostic_information.hpp>
16
#include <boost/exception/exception.hpp>
17
#endif
18

19
#include <cstddef>
20
#include <cstdint>
21
#include <exception>
22
#include <stdexcept>
23
#include <string>
24
#include <system_error>
25
#include <typeinfo>
26

27
#include <hpx/config/warnings_prefix.hpp>
28

29
///////////////////////////////////////////////////////////////////////////////
30
namespace hpx::serialization {
31

32
    namespace detail {
33
        ///////////////////////////////////////////////////////////////////////////
×
34
        // TODO: This is not scalable, and painful to update.
35
        void save(output_archive& ar, std::exception_ptr const& ep,
36
            unsigned int /* version */)
×
37
        {
38
            auto type = hpx::util::exception_type::unknown_exception;
×
39
            std::string what;
40
            auto err_value = hpx::error::success;
41
            std::string err_message;
42

43
            std::string throw_function_;
×
44
            std::string throw_file_;
45
            long throw_line_ = 0;
46

47
            // retrieve information related to exception_info
48
            try
×
49
            {
50
                std::rethrow_exception(ep);
×
51
            }
52
            catch (exception_info const& xi)
×
53
            {
54
                if (std::string const* function =
55
                        xi.get<hpx::detail::throw_function>())
56
                {
57
                    throw_function_ = *function;
58
                }
×
59

60
                if (std::string const* file = xi.get<hpx::detail::throw_file>())
61
                {
62
                    throw_file_ = *file;
63
                }
×
64

65
                if (long const* line = xi.get<hpx::detail::throw_line>())
×
66
                {
67
                    throw_line_ = *line;
×
68
                }
69
            }
70

71
            // figure out concrete underlying exception type
72
            try
×
73
            {
74
                std::rethrow_exception(ep);
×
75
            }
76
            catch (hpx::thread_interrupted const&)
×
77
            {
78
                type =
79
                    hpx::util::exception_type::hpx_thread_interrupted_exception;
×
80
                what = "hpx::thread_interrupted";
×
81
                err_value = hpx::error::thread_cancelled;
×
82
            }
83
            catch (hpx::exception const& e)
×
84
            {
×
85
                type = hpx::util::exception_type::hpx_exception;
×
86
                what = e.what();
×
87
                err_value = e.get_error();
×
88
            }
89
            catch (std::system_error const& e)
×
90
            {
×
91
                type = hpx::util::exception_type::std_system_error;
×
92
                what = e.what();
×
93
                err_value = static_cast<hpx::error>(e.code().value());
×
94
                err_message = e.code().message();
×
95
            }
96
            catch (std::runtime_error const& e)
×
97
            {
×
98
                type = hpx::util::exception_type::std_runtime_error;
×
99
                what = e.what();
×
100
            }
101
            catch (std::invalid_argument const& e)
×
102
            {
×
103
                type = hpx::util::exception_type::std_invalid_argument;
×
104
                what = e.what();
×
105
            }
106
            catch (std::out_of_range const& e)
×
107
            {
×
108
                type = hpx::util::exception_type::std_out_of_range;
×
109
                what = e.what();
×
110
            }
111
            catch (std::logic_error const& e)
×
112
            {
×
113
                type = hpx::util::exception_type::std_logic_error;
×
114
                what = e.what();
×
115
            }
116
            catch (std::bad_alloc const& e)
×
117
            {
×
118
                type = hpx::util::exception_type::std_bad_alloc;
×
119
                what = e.what();
×
120
            }
121
            catch (std::bad_cast const& e)
×
122
            {
×
123
                type = hpx::util::exception_type::std_bad_cast;
×
124
                what = e.what();
×
125
            }
126
            catch (std::bad_typeid const& e)
×
127
            {
×
128
                type = hpx::util::exception_type::std_bad_typeid;
×
129
                what = e.what();
×
130
            }
131
            catch (std::bad_exception const& e)
×
132
            {
×
133
                type = hpx::util::exception_type::std_bad_exception;
×
134
                what = e.what();
×
135
            }
136
            catch (std::exception const& e)
×
137
            {
×
138
                type = hpx::util::exception_type::std_exception;
×
139
                what = e.what();
140
            }
141
#if ASIO_HAS_BOOST_THROW_EXCEPTION != 0
142
            catch (boost::exception const& e)
143
            {
144
                type = hpx::util::boost_exception;
145
                what = boost::diagnostic_information(e);
146
            }
×
147
#endif
148
            catch (...)
×
149
            {
150
                type = hpx::util::exception_type::unknown_exception;
×
151
                what = "unknown exception";
152
            }
153

154
            // clang-format off
155
            ar & type & what & throw_function_ & throw_file_ & throw_line_;
156
            // clang-format on
×
157

158
            if (hpx::util::exception_type::hpx_exception == type)
159
            {
160
                // clang-format off
161
                ar << err_value;
162
                // clang-format on
×
163
            }
164
            else if (hpx::util::exception_type::boost_system_error == type ||
165
                hpx::util::exception_type::std_system_error == type)
166
            {
167
                // clang-format off
168
                ar << err_value << err_message;
169
                // clang-format on
×
170
            }
171
        }
172

173
        ///////////////////////////////////////////////////////////////////////////
×
174
        // TODO: This is not scalable, and painful to update.
175
        void load(input_archive& ar, std::exception_ptr& e,
176
            unsigned int /* version */)
177
        {
178
            auto type = hpx::util::exception_type::unknown_exception;
179
            std::string what;
180
            auto err_value = hpx::error::success;
181
            std::string err_message;
182

183
            std::string throw_function_;
184
            std::string throw_file_;
185
            int throw_line_ = 0;
186

187
            // clang-format off
188
            ar & type & what & throw_function_ & throw_file_ & throw_line_;
189
            // clang-format on
×
190

191
            if (hpx::util::exception_type::hpx_exception == type)
192
            {
193
                // clang-format off
194
                ar & err_value;
195
                ar >> err_value;
196
                // clang-format on
×
197
            }
198
            else if (hpx::util::exception_type::boost_system_error == type ||
199
                hpx::util::exception_type::std_system_error == type)
200
            {
201
                // clang-format off
202
                ar & err_value& err_message;
203
                ar >> err_value >> err_message;
204
                // clang-format on
205
            }
×
206

207
            switch (type)
208
            {
209
            case hpx::util::exception_type::std_exception:
210
                [[fallthrough]];
211

×
212
            case hpx::util::exception_type::unknown_exception:
213
                e = hpx::detail::get_exception(hpx::detail::std_exception(what),
×
214
                    throw_function_, throw_file_, throw_line_);
215
                break;
216

217
            // standard exceptions
×
218
            case hpx::util::exception_type::std_runtime_error:
219
                e = hpx::detail::get_exception(std::runtime_error(what),
×
220
                    throw_function_, throw_file_, throw_line_);
221
                break;
222

×
223
            case hpx::util::exception_type::std_invalid_argument:
224
                e = hpx::detail::get_exception(std::invalid_argument(what),
×
225
                    throw_function_, throw_file_, throw_line_);
226
                break;
227

×
228
            case hpx::util::exception_type::std_out_of_range:
229
                e = hpx::detail::get_exception(std::out_of_range(what),
×
230
                    throw_function_, throw_file_, throw_line_);
231
                break;
232

×
233
            case hpx::util::exception_type::std_logic_error:
234
                e = hpx::detail::get_exception(std::logic_error(what),
×
235
                    throw_function_, throw_file_, throw_line_);
236
                break;
237

×
238
            case hpx::util::exception_type::std_bad_alloc:
239
                e = hpx::detail::get_exception(hpx::detail::bad_alloc(what),
×
240
                    throw_function_, throw_file_, throw_line_);
241
                break;
242

×
243
            case hpx::util::exception_type::std_bad_cast:
244
                e = hpx::detail::get_exception(hpx::detail::bad_cast(what),
×
245
                    throw_function_, throw_file_, throw_line_);
246
                break;
247

×
248
            case hpx::util::exception_type::std_bad_typeid:
249
                e = hpx::detail::get_exception(hpx::detail::bad_typeid(what),
×
250
                    throw_function_, throw_file_, throw_line_);
251
                break;
×
252
            case hpx::util::exception_type::std_bad_exception:
253
                e = hpx::detail::get_exception(hpx::detail::bad_exception(what),
×
254
                    throw_function_, throw_file_, throw_line_);
255
                break;
256

257
#if ASIO_HAS_BOOST_THROW_EXCEPTION != 0
258
            // boost exceptions
259
            case hpx::util::boost_exception:
260
                HPX_ASSERT(false);    // shouldn't happen
261
                break;
262
#endif
263

264
            // boost::system::system_error
265
            case hpx::util::exception_type::boost_system_error:
266
                [[fallthrough]];
267

268
            // std::system_error
×
269
            case hpx::util::exception_type::std_system_error:
×
270
                e = hpx::detail::get_exception(
271
                    std::system_error(static_cast<int>(err_value),
272
                        std::system_category(), err_message),
×
273
                    throw_function_, throw_file_, throw_line_);
274
                break;
275

276
            // hpx::exception
×
277
            case hpx::util::exception_type::hpx_exception:
×
278
                e = hpx::detail::get_exception(
279
                    hpx::exception(err_value, what, hpx::throwmode::rethrow),
×
280
                    throw_function_, throw_file_, throw_line_);
281
                break;
282

×
283
            // hpx::thread_interrupted
×
284
            case hpx::util::exception_type::hpx_thread_interrupted_exception:
×
285
                e = hpx::detail::construct_lightweight_exception(
×
286
                    hpx::thread_interrupted());
287
                break;
×
288
            }
289
        }
64✔
290

291
        save_custom_exception_handler_type& get_save_custom_exception_handler()
64✔
292
        {
64✔
293
            static save_custom_exception_handler_type f = save;
294
            return f;
295
        }
64✔
296

297
        HPX_CORE_EXPORT void set_save_custom_exception_handler(
298
            save_custom_exception_handler_type f)
64✔
299
        {
64✔
300
            get_save_custom_exception_handler() = HPX_MOVE(f);
301
        }
64✔
302

303
        load_custom_exception_handler_type& get_load_custom_exception_handler()
64✔
304
        {
64✔
305
            static load_custom_exception_handler_type f = load;
306
            return f;
307
        }
64✔
308

309
        HPX_CORE_EXPORT void set_load_custom_exception_handler(
310
            load_custom_exception_handler_type f)
64✔
311
        {
64✔
312
            get_load_custom_exception_handler() = HPX_MOVE(f);
313
        }
314
    }    // namespace detail
315

316
    ///////////////////////////////////////////////////////////////////////////
×
317
    template <typename Archive>
318
    void save(Archive& ar, std::exception_ptr const& ep, unsigned int version)
×
319
    {
320
        if (detail::get_save_custom_exception_handler())
×
321
        {
322
            detail::get_save_custom_exception_handler()(ar, ep, version);
323
        }
324
        else
×
325
        {
326
            HPX_THROW_EXCEPTION(hpx::error::invalid_status,
327
                "hpx::serialization::save",
328
                "Attempted to save a std::exception_ptr, but there is no "
329
                "handler installed. Set one with "
330
                "hpx::serialization::detail::set_save_custom_exception_"
331
                "handler.");
×
332
        }
333
    }
334

335
    ///////////////////////////////////////////////////////////////////////////
×
336
    template <typename Archive>
337
    void load(Archive& ar, std::exception_ptr& ep, unsigned int version)
×
338
    {
339
        if (detail::get_load_custom_exception_handler())
×
340
        {
341
            detail::get_load_custom_exception_handler()(ar, ep, version);
342
        }
343
        else
×
344
        {
345
            HPX_THROW_EXCEPTION(hpx::error::invalid_status,
346
                "hpx::serialization::load",
347
                "Attempted to load a std::exception_ptr, but there is no "
348
                "handler installed. Set one with "
349
                "hpx::serialization::detail::set_load_custom_exception_"
350
                "handler.");
×
351
        }
352
    }
353

354
    template HPX_CORE_EXPORT void save(hpx::serialization::output_archive&,
355
        std::exception_ptr const&, unsigned int);
356

357
    template HPX_CORE_EXPORT void load(
358
        hpx::serialization::input_archive&, std::exception_ptr&, unsigned int);
359
}    // namespace hpx::serialization
360

361
#include <hpx/config/warnings_suffix.hpp>
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