Logger System 0.1.3
High-performance C++20 thread-safe logging system with asynchronous capabilities
Loading...
Searching...
No Matches
error_codes.h
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2025, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
11#pragma once
12
13#include <string>
14#include <stdexcept>
15#include <utility>
16#include <optional>
17#include <concepts>
18
19#if __has_include(<kcenon/common/patterns/result.h>)
20#include <kcenon/common/patterns/result.h>
21#define KCENON_COMMON_RESULT_AVAILABLE 1
22#elif __has_include(<common/patterns/result.h>)
23#include <common/patterns/result.h>
24#define KCENON_COMMON_RESULT_AVAILABLE 1
25#endif
26
27#if defined(KCENON_COMMON_RESULT_AVAILABLE)
28#ifndef KCENON_COMMON_RESULT_SHIM_DEFINED
29#define KCENON_COMMON_RESULT_SHIM_DEFINED
30namespace kcenon {
31namespace logger {
32using ::kcenon::common::error_info;
33template<typename T>
34using Result = ::kcenon::common::Result<T>;
35using VoidResult = ::kcenon::common::VoidResult;
36using ::kcenon::common::ok;
37using ::kcenon::common::make_error;
38} // namespace logger
39} // namespace kcenon
40#endif // KCENON_COMMON_RESULT_SHIM_DEFINED
41#else
42#ifndef KCENON_COMMON_RESULT_FALLBACK_DEFINED
43#define KCENON_COMMON_RESULT_FALLBACK_DEFINED
44namespace kcenon {
45namespace common {
46
47struct error_info {
48 int code{};
49 std::string message;
50 std::string category;
51
52 error_info() = default;
53
54 error_info(int code_value, std::string message_value)
55 : code(code_value),
56 message(std::move(message_value)),
57 category() {}
58
59 error_info(int code_value, std::string message_value, std::string category_value)
60 : code(code_value),
61 message(std::move(message_value)),
62 category(std::move(category_value)) {}
63};
64
65inline error_info make_error_info(int code_value, std::string message_value, std::string category_value) {
66 return error_info{code_value, std::move(message_value), std::move(category_value)};
67}
68
69template<typename T>
70class Result {
71public:
72 Result() = default;
73
74 explicit Result(T value)
75 : value_(std::move(value)) {}
76
77 explicit Result(error_info info)
78 : error_(std::move(info)) {}
79
80 bool has_value() const { return value_.has_value(); }
81 bool has_error() const { return error_.has_value(); }
82
83 T& value() {
84 if (!value_) {
85 throw std::logic_error("Result does not contain a value");
86 }
87 return *value_;
88 }
89
90 const T& value() const {
91 if (!value_) {
92 throw std::logic_error("Result does not contain a value");
93 }
94 return *value_;
95 }
96
98 if (!error_) {
99 throw std::logic_error("Result does not contain an error");
100 }
101 return *error_;
102 }
103
104 const error_info& error() const {
105 if (!error_) {
106 throw std::logic_error("Result does not contain an error");
107 }
108 return *error_;
109 }
110
111private:
112 std::optional<T> value_;
113 std::optional<error_info> error_;
114};
115
117public:
118 VoidResult() = default;
119
120 explicit VoidResult(error_info info)
121 : error_(std::move(info)) {}
122
123 bool has_value() const { return !error_.has_value(); }
124 bool has_error() const { return error_.has_value(); }
125
127 if (!error_) {
128 throw std::logic_error("VoidResult does not contain an error");
129 }
130 return *error_;
131 }
132
133 const error_info& error() const {
134 if (!error_) {
135 throw std::logic_error("VoidResult does not contain an error");
136 }
137 return *error_;
138 }
139
140private:
141 std::optional<error_info> error_;
142};
143
144template<typename T>
145Result<T> ok(T value) {
146 return Result<T>(std::move(value));
147}
148
149inline VoidResult ok() {
150 return VoidResult{};
151}
152
153template<typename T>
155 return Result<T>(std::move(info));
156}
157
159 return VoidResult(std::move(info));
160}
161
162template<typename T>
163bool is_ok(const Result<T>& result) {
164 return result.has_value();
165}
166
167template<typename T>
168bool is_error(const Result<T>& result) {
169 return result.has_error();
170}
171
172inline bool is_ok(const VoidResult& result) {
173 return !result.has_error();
174}
175
176inline bool is_error(const VoidResult& result) {
177 return result.has_error();
178}
179
180template<typename T>
181T& get_value(Result<T>& result) {
182 return result.value();
183}
184
185template<typename T>
186const T& get_value(const Result<T>& result) {
187 return result.value();
188}
189
190template<typename T>
192 return result.error();
193}
194
195template<typename T>
196const error_info& get_error(const Result<T>& result) {
197 return result.error();
198}
199
200inline const error_info& get_error(const VoidResult& result) {
201 return result.error();
202}
203
204namespace error_codes {
205enum class generic_error {
206 none = 0
207};
208} // namespace error_codes
209
210} // namespace common
211} // namespace kcenon
212#endif // KCENON_COMMON_RESULT_FALLBACK_DEFINED
213#endif
214
215namespace kcenon::logger {
216
225 // General errors (0-999)
226 success = 0,
227 unknown_error = 1,
228 not_implemented = 2,
230
231 // Writer errors (1000-1099)
232 writer_not_found = 1000,
235 writer_not_healthy = 1003,
236
237 // File errors (1100-1199)
238 file_open_failed = 1100,
239 file_write_failed = 1101,
242
243 // Network errors (1200-1299)
245 network_send_failed = 1201,
246 network_timeout = 1202,
247
248 // Buffer/Queue errors (1300-1399)
249 buffer_overflow = 1300,
250 queue_full = 1301,
251 queue_stopped = 1302,
254
255 // Configuration errors (1400-1499)
259
260 // Metrics errors (1500-1599)
263
264 // Processing errors (1600-1699)
265 flush_timeout = 1600,
266 processing_failed = 1601,
267 filter_error = 1602,
268 formatter_error = 1603,
271
272 // Security errors (1700-1799)
273 encryption_failed = 1700,
274 decryption_failed = 1701,
276 sanitization_failed = 1703,
277 file_read_failed = 1704,
280 invalid_key_size = 1707,
281 invalid_filename = 1708,
282
283 // DI Container errors (1800-1899)
284 di_not_available = 1800,
285 component_not_found = 1801,
286 registration_failed = 1802,
287 creation_failed = 1803,
288 operation_failed = 1804,
291
292 // Writer errors (1900-1999)
297};
298
305 switch (code) {
307 return "Success";
309 return "Unknown error";
311 return "Not implemented";
313 return "Invalid argument";
314
315 // Writer errors
317 return "Writer not found";
319 return "Writer initialization failed";
321 return "Writer already exists";
323 return "Writer not healthy";
324
325 // File errors
327 return "Failed to open file";
329 return "Failed to write to file";
331 return "File rotation failed";
333 return "File permission denied";
334
335 // Network errors
337 return "Network connection failed";
339 return "Network send failed";
341 return "Network timeout";
342
343 // Buffer/Queue errors
345 return "Buffer overflow";
347 return "Queue is full";
349 return "Queue is stopped";
351 return "Queue overflow: messages dropped";
353 return "Queue overflow: operation blocked";
354
355 // Configuration errors
357 return "Invalid configuration";
359 return "Configuration missing";
361 return "Configuration conflict";
362
363 // Metrics errors
365 return "Metrics collection failed";
367 return "Metrics not available";
368
369 // Processing errors
371 return "Flush timeout";
373 return "Processing failed";
375 return "Filter error";
377 return "Formatter error";
379 return "Batch processing timeout";
381 return "Batch processing failed";
382
383 // Security errors
385 return "Encryption failed";
387 return "Decryption failed";
389 return "Authentication failed";
391 return "Sanitization failed";
393 return "Failed to read file";
395 return "Insecure file permissions";
397 return "Path traversal attack detected";
399 return "Invalid encryption key size";
401 return "Invalid filename";
402
403 // DI Container errors
405 return "DI container not available";
407 return "Component not found in DI container";
409 return "Failed to register component in DI container";
411 return "Failed to create component from factory";
413 return "DI container operation failed";
415 return "Async operation not running";
417 return "Async operation already running";
418
419 // Writer errors
421 return "Writer not available";
423 return "Writer configuration error";
425 return "Writer operation failed";
427 return "Destructor cleanup failed";
428
429 default:
430 return "Unknown logger error code";
431 }
432}
433
434// Result wrapper built on top of common_system Result pattern
435template<typename T>
436class result {
437public:
438 // Move constructor (only enabled for move-constructible types)
439 result(T&& value) requires std::move_constructible<T>
440 : value_(common::ok<T>(std::move(value))) {}
441
442 // Copy constructor (only enabled for copyable types that are not rvalue references)
443 result(const T& value) requires std::copy_constructible<T>
445
446 result(logger_error_code code, const std::string& msg = "")
447 : value_(common::error_info{
448 static_cast<int>(code),
449 msg.empty() ? logger_error_to_string(code) : msg,
450 "logger_system"}) {}
451
452 explicit result(const common::error_info& error)
453 : value_(error) {}
454
455 explicit result(common::error_info&& error)
456 : value_(std::move(error)) {}
457
458 // Static factory method to avoid constructor ambiguity
459 static result ok_value(const T& value) {
461 // Directly assign common::Result value
463 return res;
464 }
465
466 bool has_value() const { return value_.is_ok(); }
467 explicit operator bool() const { return has_value(); }
468
469 T& value() { return value_.value(); }
470 const T& value() const { return value_.value(); }
471
473 return static_cast<logger_error_code>(value_.error().code);
474 }
475
476 const std::string& error_message() const {
477 return value_.error().message;
478 }
479
480 const common::Result<T>& raw() const { return value_; }
481
482private:
484};
485
486// ============================================================================
487// Helper functions for common::VoidResult with logger error codes
488// ============================================================================
489
506inline common::VoidResult make_logger_void_result(logger_error_code code, const std::string& message = "") {
508 static_cast<int>(code),
509 message.empty() ? logger_error_to_string(code) : message,
510 "logger_system"
511 });
512}
513
529
544 if (!result.is_err()) {
546 }
547 return static_cast<logger_error_code>(result.error().code);
548}
549
557 return result.is_err();
558}
559
567 if (!result.is_err()) {
568 return "";
569 }
570 return result.error().message;
571}
572
574
575} // namespace kcenon::logger
const error_info & error() const
std::optional< T > value_
bool has_error() const
Definition error_codes.h:81
error_info & error()
Definition error_codes.h:97
const T & value() const
Definition error_codes.h:90
bool has_value() const
Definition error_codes.h:80
Result(error_info info)
Definition error_codes.h:77
std::optional< error_info > error_
const error_info & error() const
VoidResult(error_info info)
std::optional< error_info > error_
const T & value() const
result(const T &value)
result(common::error_info &&error)
result(const common::error_info &error)
common::Result< T > value_
const std::string & error_message() const
static result ok_value(const T &value)
const common::Result< T > & raw() const
result(logger_error_code code, const std::string &msg="")
logger_error_code error_code() const
bool is_ok(const Result< T > &result)
error_info make_error_info(int code_value, std::string message_value, std::string category_value)
Definition error_codes.h:65
Result< T > error(error_info info)
VoidResult ok()
T & get_value(Result< T > &result)
error_info & get_error(Result< T > &result)
bool is_error(const Result< T > &result)
common::VoidResult make_logger_void_success()
logger_error_code
Error codes specific to the logger system.
common::VoidResult make_logger_void_result(logger_error_code code, const std::string &message="")
std::string get_logger_error_message(const common::VoidResult &result)
Get error message from a VoidResult.
logger_error_code get_logger_error_code(const common::VoidResult &result)
std::string logger_error_to_string(logger_error_code code)
Convert logger_error_code to string representation.
bool has_logger_error(const common::VoidResult &result)
Check if a VoidResult contains an error.
error_info(int code_value, std::string message_value)
Definition error_codes.h:54
error_info(int code_value, std::string message_value, std::string category_value)
Definition error_codes.h:59