Thread System 0.3.1
High-performance C++20 thread pool with work stealing and DAG scheduling
Loading...
Searching...
No Matches
error_handling.h
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2024, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
5#pragma once
6
20#include <string>
21#include <string_view>
22#include <system_error>
23
24// Include common_system Result types
25#include <kcenon/common/patterns/result.h>
26
27namespace kcenon::thread {
28
47enum class error_code {
48 // General errors (-100 to -109)
49 success = 0,
50 unknown_error = -101,
51 operation_canceled = -102,
52 operation_timeout = -103,
53 not_implemented = -104,
54 invalid_argument = -105,
55
56 // Thread errors (-110 to -119)
58 thread_not_running = -111,
61
62 // Queue errors (-120 to -129)
63 queue_full = -120,
64 queue_empty = -121,
65 queue_stopped = -122,
66 queue_busy = -123, // Queue is temporarily busy with concurrent operations
67
68 // Job errors (-130 to -139)
71 job_invalid = -132,
72
73 // Resource errors (-140 to -149)
76
77 // Synchronization errors (-150 to -159)
78 mutex_error = -150,
79 deadlock_detected = -151,
81
82 // IO errors (-160 to -169)
83 io_error = -160,
84 file_not_found = -161,
85
86 // Circuit breaker errors (-170 to -179)
87 circuit_open = -170,
88 circuit_half_open = -171
89};
90
91// Compile-time validation for error code range
92static_assert(static_cast<int>(error_code::unknown_error) >= -199 &&
93 static_cast<int>(error_code::unknown_error) <= -100,
94 "error_code values must be in range [-199, -100]");
95static_assert(static_cast<int>(error_code::file_not_found) >= -199 &&
96 static_cast<int>(error_code::file_not_found) <= -100,
97 "error_code values must be in range [-199, -100]");
98
104inline std::string error_code_to_string(error_code code) {
105 using map_entry = std::pair<error_code, std::string_view>;
106 static constexpr map_entry kMap[] = {
107 {error_code::success, "Success"},
108 {error_code::unknown_error, "Unknown error"},
109 {error_code::operation_canceled, "Operation canceled"},
110 {error_code::operation_timeout, "Operation timed out"},
111 {error_code::not_implemented, "Not implemented"},
112 {error_code::invalid_argument, "Invalid argument"},
113 {error_code::thread_already_running, "Thread is already running"},
114 {error_code::thread_not_running, "Thread is not running"},
115 {error_code::thread_start_failure, "Failed to start thread"},
116 {error_code::thread_join_failure, "Failed to join thread"},
117 {error_code::queue_full, "Queue is full"},
118 {error_code::queue_empty, "Queue is empty"},
119 {error_code::queue_stopped, "Queue is stopped"},
120 {error_code::queue_busy, "Queue is busy"},
121 {error_code::job_creation_failed, "Failed to create job"},
122 {error_code::job_execution_failed, "Failed to execute job"},
123 {error_code::job_invalid, "Invalid job"},
124 {error_code::resource_allocation_failed, "Failed to allocate resource"},
125 {error_code::resource_limit_reached, "Resource limit reached"},
126 {error_code::mutex_error, "Mutex error"},
127 {error_code::deadlock_detected, "Deadlock detected"},
128 {error_code::condition_variable_error, "Condition variable error"},
129 {error_code::io_error, "I/O error"},
130 {error_code::file_not_found, "File not found"},
131 {error_code::circuit_open, "Circuit breaker is open"},
132 {error_code::circuit_half_open, "Circuit breaker is in half-open state"},
133 };
134 for (const auto& [k, v] : kMap) {
135 if (k == code) return std::string(v);
136 }
137 return std::string("Unknown error code");
138}
139
140// ============================================================================
141// common::Result Integration Utilities
142// ============================================================================
143
156inline common::error_info to_error_info(error_code code, const std::string& message = "") {
157 return common::error_info{
158 static_cast<int>(code),
159 message.empty() ? error_code_to_string(code) : message,
160 "thread_system"
161 };
162}
163
178inline common::VoidResult make_error_result(error_code code, const std::string& message = "") {
179 return common::VoidResult(to_error_info(code, message));
180}
181
199template<typename T>
200common::Result<T> make_error_result(error_code code, const std::string& message = "") {
201 return common::Result<T>(to_error_info(code, message));
202}
203
220inline error_code get_error_code(const common::error_info& info) {
221 return static_cast<error_code>(info.code);
222}
223
224// ============================================================================
225// std::error_code Integration
226// ============================================================================
227
235class thread_error_category : public std::error_category {
236public:
240 [[nodiscard]] const char* name() const noexcept override {
241 return "thread_system";
242 }
243
249 [[nodiscard]] std::string message(int ev) const override {
250 return error_code_to_string(static_cast<error_code>(ev));
251 }
252
259 [[nodiscard]] bool equivalent(int ev, const std::error_condition& condition) const noexcept override {
260 switch (static_cast<error_code>(ev)) {
262 return condition == std::errc::invalid_argument;
265 return condition == std::errc::not_enough_memory;
267 return condition == std::errc::timed_out;
269 return condition == std::errc::resource_deadlock_would_occur;
270 default:
271 return false;
272 }
273 }
274};
275
280inline const std::error_category& thread_category() noexcept {
281 static thread_error_category instance;
282 return instance;
283}
284
290inline std::error_code make_error_code(error_code e) noexcept {
291 return std::error_code(static_cast<int>(e), thread_category());
292}
293
299inline std::error_condition make_error_condition(error_code e) noexcept {
300 return std::error_condition(static_cast<int>(e), thread_category());
301}
302
303} // namespace kcenon::thread
304
305// ============================================================================
306// std::error_code specialization (required to be in global namespace)
307// ============================================================================
308
309namespace std {
314template <>
315struct is_error_code_enum<kcenon::thread::error_code> : true_type {};
316} // namespace std
std::error_category implementation for thread_system errors
const char * name() const noexcept override
Returns the name of the error category.
std::string message(int ev) const override
Returns a message for the given error code.
bool equivalent(int ev, const std::error_condition &condition) const noexcept override
Returns the equivalent std::errc for certain error codes.
Core threading foundation of the thread system library.
Definition thread_impl.h:17
common::VoidResult make_error_result(error_code code, const std::string &message="")
Create a common::VoidResult error from a thread::error_code.
error_code
Strongly typed error codes for thread system operations.
@ circuit_half_open
Circuit breaker is in half-open state.
@ circuit_open
Circuit breaker is open, request rejected.
std::error_condition make_error_condition(error_code e) noexcept
Creates a std::error_condition from a thread_system error_code.
std::error_code make_error_code(error_code e) noexcept
Creates a std::error_code from a thread_system error_code.
error_code get_error_code(const common::error_info &info)
Extract thread::error_code from a common::error_info.
const std::error_category & thread_category() noexcept
Gets the singleton instance of thread_error_category.
common::error_info to_error_info(error_code code, const std::string &message="")
Convert a thread::error_code to common::error_info.
@ info
Informational messages highlighting progress.
std::string error_code_to_string(error_code code)
Converts an error_code to a string representation.
STL namespace.