PDI 1.12.0-alpha.2026-05-07

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 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of CEA nor the names of its contributors may be used to
14 * endorse or promote products derived from this software without specific
15 * prior written permission.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 ******************************************************************************/
25
26#ifndef PDI_ERROR_H_
27#define PDI_ERROR_H_
28
29#include <concepts>
30#include <exception>
31#include <iostream>
32#include <ranges>
33#include <sstream>
34#include <stdexcept>
35#include <string>
36
37#include <spdlog/spdlog.h>
38
39#include <pdi/pdi_fwd.h>
40#include <pdi/paraconf_wrapper.h>
41
42namespace PDI {
43
45template <typename R>
47 = std::ranges::input_range<R> && std::ranges::sized_range<R> && std::convertible_to<std::ranges::range_reference_t<R>, std::exception_ptr>;
48
57class PDI_EXPORT Error: virtual public std::exception
58{
59public:
60 virtual ~Error() noexcept;
61
65 virtual PDI_status_t status() const noexcept = 0;
66
70 [[noreturn]] virtual void rethrow_with_context(std::string context) const = 0;
71
78 virtual std::string full_msg() const = 0;
79
84 template <typename... Args>
85 [[noreturn]] void inline rethrow_with_context(fmt::format_string<Args...> format_str, Args&&... args) const
86 {
87 rethrow_with_context(fmt::format(format_str, std::forward<Args>(args)...));
88 std::abort(); // rethrow_with_context should never return, this is just to silence compiler warnings
89 }
90};
91
92namespace impl {
93
95class PDI_EXPORT what_impl: virtual public std::exception
96{
97private:
99 std::string m_what;
100
101protected:
105 what_impl(std::string what) noexcept;
106
107public:
108 const char* what() const noexcept override;
109};
110
112template <PDI_status_t STATUS>
113class PDI_EXPORT status_impl: virtual public Error
114{
115public:
116 PDI_status_t status() const noexcept override { return STATUS; }
117};
118
120template <PDI_status_t STATUS>
121class PDI_EXPORT Error_impl
122 : public what_impl
123 , public status_impl<STATUS>
124{
125public:
129 Error_impl(std::string what) noexcept;
130
135 template <typename... Args>
136 inline Error_impl(fmt::format_string<Args...> format_str, Args&&... args) noexcept
137 : Error_impl(fmt::format(format_str, std::forward<Args>(args)...))
138 {}
139
140 using what_impl::what;
141
142 using status_impl<STATUS>::status;
143
144 std::string full_msg() const override;
145
146 [[noreturn]] void rethrow_with_context(std::string msg) const override;
147};
148
149} // namespace impl
150
153using Value_error = impl::Error_impl<PDI_ERR_VALUE>;
154extern template class PDI_EXPORT impl::Error_impl<PDI_ERR_VALUE>;
155
158using Plugin_error = impl::Error_impl<PDI_ERR_PLUGIN>;
159extern template class PDI_EXPORT impl::Error_impl<PDI_ERR_PLUGIN>;
160
163using Impl_error = impl::Error_impl<PDI_ERR_IMPL>;
164extern template class PDI_EXPORT impl::Error_impl<PDI_ERR_IMPL>;
165
169using State_error = impl::Error_impl<PDI_ERR_STATE>;
170extern template class PDI_EXPORT impl::Error_impl<PDI_ERR_STATE>;
171
174using Permission_error = impl::Error_impl<PDI_ERR_PERMISSION>;
175extern template class PDI_EXPORT impl::Error_impl<PDI_ERR_PERMISSION>;
176
179using System_error = impl::Error_impl<PDI_ERR_SYSTEM>;
180extern template class PDI_EXPORT impl::Error_impl<PDI_ERR_SYSTEM>;
181
184using Type_error = impl::Error_impl<PDI_ERR_TYPE>;
185extern template class PDI_EXPORT impl::Error_impl<PDI_ERR_TYPE>;
186
189using Invalid_action_error = impl::Error_impl<PDI_ERR_INVALIDACTION>;
190extern template class PDI_EXPORT impl::Error_impl<PDI_ERR_INVALIDACTION>;
191
194class PDI_EXPORT Spectree_error
195 : public impl::what_impl
196 , public impl::status_impl<PDI_ERR_SPECTREE>
197{
198private:
199 std::optional<Yaml_region> m_location;
200
201 Spectree_error(std::optional<Yaml_region> location, std::string what);
202
203public:
208 Spectree_error(PC_tree_t tree, std::string what);
209
215 template <typename... Args>
216 inline Spectree_error(PC_tree_t tree, fmt::format_string<Args...> format_str, Args&&... args)
217 : Spectree_error(tree, fmt::format(format_str, std::forward<Args>(args)...))
218 {}
219
220 using what_impl::what;
221
223
224 std::string full_msg() const override;
225
226 [[noreturn]] void rethrow_with_context(std::string msg) const override;
227};
228
231class PDI_EXPORT Multiple_errors
232 : public impl::status_impl<PDI_ERR_MULTIPLE>
233 , public impl::what_impl
234{
235private:
237 std::vector<std::exception_ptr> m_nested_ptrs;
238
239public:
244 Multiple_errors(std::vector<std::exception_ptr> causes, std::string what) noexcept;
245
251 template <typename... Args>
252 inline Multiple_errors(range_of_exception_ptrs auto&& causes, fmt::format_string<Args...> format_str, Args&&... args) noexcept
253 : Multiple_errors(std::vector<std::exception_ptr>(causes.begin(), causes.end()), fmt::format(format_str, std::forward<Args>(args)...))
254 {}
255
259 std::vector<std::exception_ptr> const & nested_ptrs() const;
260
261 using status_impl::status;
262
263 using what_impl::what;
264
265 std::string full_msg() const override;
266
267 [[noreturn]] void rethrow_with_context(std::string msg) const override;
268};
269
275[[noreturn]] void PDI_EXPORT rethrow_with_simple_context(std::exception_ptr err, std::string msg);
276
283template <typename... Args>
284[[noreturn]] static inline void rethrow_with_context(std::exception_ptr err, fmt::format_string<Args...> format_str, Args&&... args)
285{
286 rethrow_with_simple_context(err, fmt::format(format_str, std::forward<Args>(args)...));
287}
288
298void PDI_EXPORT rethrow_with_simple_context(std::vector<std::exception_ptr> errors, std::string msg);
299
310template <typename... Args>
311static inline void rethrow_with_context(range_of_exception_ptrs auto&& errors, fmt::format_string<Args...> format_str, Args&&... args)
312{
313 rethrow_with_simple_context(std::vector<std::exception_ptr>(errors.begin(), errors.end()), fmt::format(format_str, std::forward<Args>(args)...));
314}
315
316} // namespace PDI
317
318#endif // PDI_ERROR_H_
An error class from which all PDI error are children.
Definition error.h:58
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:252
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:216
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:47
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:174
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:189
impl::Error_impl< PDI_ERR_VALUE > Value_error
An error class to use when a value expression is invalid.
Definition error.h:153
impl::Error_impl< PDI_ERR_TYPE > Type_error
An error class to use for invalid types.
Definition error.h:184
impl::Error_impl< PDI_ERR_IMPL > Impl_error
An error class to use for implementation limitations (typically an unimplemented feature).
Definition error.h:163
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:169
impl::Error_impl< PDI_ERR_SYSTEM > System_error
An error class to use when a system error occurred (OS, etc.).
Definition error.h:179
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:158
Definition ref_any.h:737