PDI 1.13.0

the PDI data interface

error.h
1/*******************************************************************************
2 * Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA)
3 * Copyright (C) 2021 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC)
4 * Copyright (C) 2026 Julien Bigot <julien@julien-bigot.fr>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * * Neither the name of CEA nor the names of its contributors may be used to
15 * endorse or promote products derived from this software without specific
16 * prior written permission.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
25 ******************************************************************************/
26
27#ifndef PDI_ERROR_H_
28#define PDI_ERROR_H_
29
30#include <concepts>
31#include <exception>
32#include <iostream>
33#include <ranges>
34#include <sstream>
35#include <stdexcept>
36#include <string>
37
38#include <spdlog/spdlog.h>
39
40#include <pdi/pdi_fwd.h>
41#include <pdi/paraconf_wrapper.h>
42
43namespace PDI {
44
46template <typename R>
48 = std::ranges::input_range<R> && std::ranges::sized_range<R> && std::convertible_to<std::ranges::range_reference_t<R>, std::exception_ptr>;
49
58class PDI_EXPORT Error: virtual public std::exception
59{
60public:
61 virtual ~Error() noexcept;
62
66 virtual PDI_status_t status() const noexcept = 0;
67
71 [[noreturn]] virtual void rethrow_with_context(std::string context) const = 0;
72
79 virtual std::string full_msg() const = 0;
80
85 template <typename... Args>
86 [[noreturn]] void inline rethrow_with_context(fmt::format_string<Args...> format_str, Args&&... args) const
87 {
88 rethrow_with_context(fmt::format(format_str, std::forward<Args>(args)...));
89 std::abort(); // rethrow_with_context should never return, this is just to silence compiler warnings
90 }
91};
92
93namespace impl {
94
96class PDI_EXPORT What_impl: virtual public std::exception
97{
98private:
100 std::string m_what;
101
102protected:
106 What_impl(std::string what) noexcept;
107
108public:
109 const char* what() const noexcept override;
110};
111
113template <PDI_status_t STATUS>
114class PDI_EXPORT Status_impl: virtual public Error
115{
116public:
117 PDI_status_t status() const noexcept override { return STATUS; }
118};
119
121template <PDI_status_t STATUS>
122class PDI_EXPORT Error_impl
123 : public What_impl
124 , public Status_impl<STATUS>
125{
126public:
130 Error_impl(std::string what) noexcept;
131
136 template <typename... Args>
137 inline Error_impl(fmt::format_string<Args...> format_str, Args&&... args) noexcept
138 : Error_impl(fmt::format(format_str, std::forward<Args>(args)...))
139 {}
140
141 using What_impl::what;
142
143 using Status_impl<STATUS>::status;
144
145 std::string full_msg() const override;
146
147 [[noreturn]] void rethrow_with_context(std::string msg) const override;
148};
149
150} // namespace impl
151
154using Value_error = impl::Error_impl<PDI_ERR_VALUE>;
155extern template class PDI_EXPORT impl::Error_impl<PDI_ERR_VALUE>;
156
159using Plugin_error = impl::Error_impl<PDI_ERR_PLUGIN>;
160extern template class PDI_EXPORT impl::Error_impl<PDI_ERR_PLUGIN>;
161
164using Impl_error = impl::Error_impl<PDI_ERR_IMPL>;
165extern template class PDI_EXPORT impl::Error_impl<PDI_ERR_IMPL>;
166
170using State_error = impl::Error_impl<PDI_ERR_STATE>;
171extern template class PDI_EXPORT impl::Error_impl<PDI_ERR_STATE>;
172
175using Permission_error = impl::Error_impl<PDI_ERR_PERMISSION>;
176extern template class PDI_EXPORT impl::Error_impl<PDI_ERR_PERMISSION>;
177
180using System_error = impl::Error_impl<PDI_ERR_SYSTEM>;
181extern template class PDI_EXPORT impl::Error_impl<PDI_ERR_SYSTEM>;
182
185using Type_error = impl::Error_impl<PDI_ERR_TYPE>;
186extern template class PDI_EXPORT impl::Error_impl<PDI_ERR_TYPE>;
187
190using Invalid_action_error = impl::Error_impl<PDI_ERR_INVALIDACTION>;
191extern template class PDI_EXPORT impl::Error_impl<PDI_ERR_INVALIDACTION>;
192
195class PDI_EXPORT Spectree_error
196 : public impl::What_impl
197 , public impl::Status_impl<PDI_ERR_SPECTREE>
198{
199private:
200 std::optional<Yaml_region> m_location;
201
202 Spectree_error(std::optional<Yaml_region> location, std::string what);
203
204public:
209 Spectree_error(PC_tree_t tree, std::string what);
210
216 template <typename... Args>
217 inline Spectree_error(PC_tree_t tree, fmt::format_string<Args...> format_str, Args&&... args)
218 : Spectree_error(tree, fmt::format(format_str, std::forward<Args>(args)...))
219 {}
220
221 using What_impl::what;
222
224
225 std::string full_msg() const override;
226
227 [[noreturn]] void rethrow_with_context(std::string msg) const override;
228};
229
232class PDI_EXPORT Multiple_errors
233 : public impl::Status_impl<PDI_ERR_MULTIPLE>
234 , public impl::What_impl
235{
236private:
238 std::vector<std::exception_ptr> m_nested_ptrs;
239
240public:
245 Multiple_errors(std::vector<std::exception_ptr> causes, std::string what) noexcept;
246
252 template <typename... Args>
253 inline Multiple_errors(range_of_exception_ptrs auto&& causes, fmt::format_string<Args...> format_str, Args&&... args) noexcept
254 : Multiple_errors(std::vector<std::exception_ptr>(causes.begin(), causes.end()), fmt::format(format_str, std::forward<Args>(args)...))
255 {}
256
260 std::vector<std::exception_ptr> const & nested_ptrs() const;
261
262 using Status_impl::status;
263
264 using What_impl::what;
265
266 std::string full_msg() const override;
267
268 [[noreturn]] void rethrow_with_context(std::string msg) const override;
269};
270
276[[noreturn]] void PDI_EXPORT rethrow_with_simple_context(std::exception_ptr err, std::string msg);
277
284template <typename... Args>
285[[noreturn]] static inline void rethrow_with_context(std::exception_ptr err, fmt::format_string<Args...> format_str, Args&&... args)
286{
287 rethrow_with_simple_context(err, fmt::format(format_str, std::forward<Args>(args)...));
288}
289
299void PDI_EXPORT rethrow_with_simple_context(std::vector<std::exception_ptr> errors, std::string msg);
300
311template <typename... Args>
312static inline void rethrow_with_context(range_of_exception_ptrs auto&& errors, fmt::format_string<Args...> format_str, Args&&... args)
313{
314 rethrow_with_simple_context(std::vector<std::exception_ptr>(errors.begin(), errors.end()), fmt::format(format_str, std::forward<Args>(args)...));
315}
316
317} // namespace PDI
318
319#endif // PDI_ERROR_H_
An error class from which all PDI error are children.
Definition error.h:59
virtual std::string full_msg() const =0
Gives access to a full error message.
virtual PDI_status_t status() const noexcept=0
Gives access to the status of the error.
virtual ~Error() noexcept
virtual void rethrow_with_context(std::string context) const =0
Rethrow the error with some context prepended to its description.
std::vector< std::exception_ptr > const & nested_ptrs() const
Gives access to the list or original errors.
std::string full_msg() const override
Gives access to a full error message.
Multiple_errors(range_of_exception_ptrs auto &&causes, fmt::format_string< Args... > format_str, Args &&... args) noexcept
Creates a new Multiple_errors.
Definition error.h:253
Multiple_errors(std::vector< std::exception_ptr > causes, std::string what) noexcept
Creates a new Multiple_errors.
void rethrow_with_context(std::string msg) const override
Rethrow the error with some context prepended to its description.
std::string full_msg() const override
Gives access to a full error message.
void rethrow_with_context(std::string msg) const override
Rethrow the error with some context prepended to its description.
Spectree_error(PC_tree_t tree, fmt::format_string< Args... > format_str, Args &&... args)
Creates a new Spectree_error.
Definition error.h:217
Spectree_error(PC_tree_t tree, std::string what)
Creates a new Spectree_error.
A concept that represent a "range" (list) of errors, in any kind of storage.
Definition error.h:48
PDI_status_t
Error codes of PDI.
Definition pdi.h:80
Definition array_datatype.h:38
impl::Error_impl< PDI_ERR_PERMISSION > Permission_error
An error class to use when a conflict of ownership over a content has been raised.
Definition error.h:175
impl::Error_impl< PDI_ERR_INVALIDACTION > Invalid_action_error
An error class to use when an action described in the specification tree is invalid.
Definition error.h:190
impl::Error_impl< PDI_ERR_VALUE > Value_error
An error class to use when a value expression is invalid.
Definition error.h:154
impl::Error_impl< PDI_ERR_TYPE > Type_error
An error class to use for invalid types.
Definition error.h:185
impl::Error_impl< PDI_ERR_IMPL > Impl_error
An error class to use for implementation limitations (typically an unimplemented feature).
Definition error.h:164
impl::Error_impl< PDI_ERR_STATE > State_error
An error class to use when a call to a function has been made at a wrong time (e.g.
Definition error.h:170
impl::Error_impl< PDI_ERR_SYSTEM > System_error
An error class to use when a system error occurred (OS, etc.).
Definition error.h:180
void rethrow_with_simple_context(std::exception_ptr err, std::string msg)
Throws a new exception by adding context to an existing exception.
impl::Error_impl< PDI_ERR_PLUGIN > Plugin_error
An error class to use when trying to load a non-existing plugin.
Definition error.h:159
Definition ref_any.h:737