Logger System 0.1.3
High-performance C++20 thread-safe logging system with asynchronous capabilities
Loading...
Searching...
No Matches
error_handling_utils.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
14#include <kcenon/common/config/feature_flags.h>
15#include <filesystem>
16#include <system_error>
17#include <chrono>
18#include <sstream>
19#include <iostream>
20
21#if KCENON_HAS_SOURCE_LOCATION
22# include <source_location>
23#endif
24
25// Legacy alias for backward compatibility
26#ifndef LOGGER_HAS_SOURCE_LOCATION
27# define LOGGER_HAS_SOURCE_LOCATION KCENON_HAS_SOURCE_LOCATION
28#endif
29
30namespace kcenon::logger::utils {
31
44 std::string message;
45 std::string operation; // Operation being performed
46 std::string source_file; // Source file where error occurred
47 int source_line; // Line number where error occurred
48 std::string function_name; // Function where error occurred
49 std::chrono::system_clock::time_point timestamp;
50
51#if KCENON_HAS_SOURCE_LOCATION
61 std::string error_message,
62 std::string op = "",
63 std::source_location loc = std::source_location::current()
64 ) : code(error_code),
65 message(std::move(error_message)),
66 operation(std::move(op)),
67 source_file(loc.file_name()),
68 source_line(static_cast<int>(loc.line())),
70 timestamp(std::chrono::system_clock::now()) {}
71#else
82 std::string error_message,
83 std::string op = "",
84 std::string file = "",
85 int line = 0
86 ) : code(error_code),
87 message(std::move(error_message)),
88 operation(std::move(op)),
89 source_file(std::move(file)),
90 source_line(line),
91 function_name(""),
92 timestamp(std::chrono::system_clock::now()) {}
93#endif
94
99 std::string to_string() const {
100 std::ostringstream oss;
101 oss << "[" << logger_error_to_string(code) << "]";
102 if (!message.empty()) {
103 oss << " " << message;
104 }
105 if (!operation.empty()) {
106 oss << " (during: " << operation << ")";
107 }
108 if (!source_file.empty()) {
109 oss << " at " << source_file;
110 if (source_line > 0) {
111 oss << ":" << source_line;
112 }
113 }
114 if (!function_name.empty()) {
115 oss << " in " << function_name << "()";
116 }
117 return oss.str();
118 }
119};
120
129inline void log_error_context(const error_context& context) {
130 std::cerr << "[logger_system] Error: " << context.to_string() << std::endl;
131}
132
155template<typename F>
157 F&& operation,
159) {
160 try {
161 return operation();
162 }
163 catch (const std::filesystem::filesystem_error& e) {
164 // Filesystem-specific errors (permission denied, disk full, etc.)
167 std::string("Filesystem error: ") + e.what()
168 );
169 }
170 catch (const std::ios_base::failure& e) {
171 // I/O operation failures (stream errors, write errors, etc.)
174 std::string("I/O error: ") + e.what()
175 );
176 }
177 catch (const std::system_error& e) {
178 // System-level errors
180 default_error_code,
181 std::string("System error: ") + e.what()
182 );
183 }
184 catch (const std::bad_alloc& e) {
185 // Memory allocation failures
188 std::string("Memory allocation failed: ") + e.what()
189 );
190 }
191 catch (const std::exception& e) {
192 // Generic exception catch-all
194 default_error_code,
195 std::string("Unexpected error: ") + e.what()
196 );
197 }
198 catch (...) {
199 // Non-standard exception
201 default_error_code,
202 "Unknown error (non-standard exception)"
203 );
204 }
205}
206
217template<typename F>
219 return try_write_operation(
220 std::forward<F>(operation),
222 );
223}
224
235template<typename F>
237 return try_write_operation(
238 std::forward<F>(operation),
240 );
241}
242
253template<typename F>
255 return try_write_operation(
256 std::forward<F>(operation),
258 );
259}
260
283 bool condition,
285 const std::string& message
286) {
287 if (!condition) {
288 return make_logger_void_result(error_code, message);
289 }
290 return common::ok();
291}
292
304template<typename Stream>
306 const Stream& stream,
307 const std::string& operation_name = "operation"
308) {
309 if (!stream.good()) {
310 if (stream.eof()) {
313 "Stream error: Unexpected end of file during " + operation_name
314 );
315 }
316 if (stream.fail()) {
319 "Stream error: Logical error during " + operation_name
320 );
321 }
322 if (stream.bad()) {
325 "Stream error: Read/write error during " + operation_name
326 );
327 }
330 "Stream is in an error state after " + operation_name
331 );
332 }
333 return common::ok();
334}
335
344inline common::VoidResult check_file_exists(const std::filesystem::path& path) {
345 try {
346 if (!std::filesystem::exists(path)) {
349 "File does not exist: " + path.string()
350 );
351 }
352 return common::ok();
353 } catch (const std::filesystem::filesystem_error& e) {
356 std::string("Cannot access file: ") + e.what()
357 );
358 }
359}
360
369inline common::VoidResult ensure_directory_exists(const std::filesystem::path& dir) {
370 if (dir.empty()) {
371 return common::ok(); // Empty path is valid (current directory)
372 }
373
374 return try_open_operation([&]() -> common::VoidResult {
375 if (!std::filesystem::exists(dir)) {
376 if (!std::filesystem::create_directories(dir)) {
379 "Failed to create directory: " + dir.string()
380 );
381 }
382 }
383 return common::ok();
384 });
385}
386
409template<typename F>
411 const std::string& operation_name,
412 F&& operation
413) noexcept {
414 try {
415 operation();
416 }
417 catch (const std::exception& e) {
418 error_context ctx(
420 e.what(),
421 operation_name
422 );
424 }
425 catch (...) {
426 error_context ctx(
428 "Unknown exception",
429 operation_name
430 );
432 }
433}
434
445template<typename F>
447 const std::string& operation_name,
448 F&& operation
449) noexcept {
450 try {
451 auto result = operation();
452 if (result.is_err()) {
453 error_context ctx(
455 result.error().message,
456 operation_name
457 );
459 }
460 }
461 catch (const std::exception& e) {
462 error_context ctx(
464 e.what(),
465 operation_name
466 );
468 }
469 catch (...) {
470 error_context ctx(
472 "Unknown exception",
473 operation_name
474 );
476 }
477}
478
479} // namespace kcenon::logger::utils
Error codes specific to the logger system.
VoidResult ok()
void safe_destructor_operation(const std::string &operation_name, F &&operation) noexcept
Safe operation execution for destructors.
common::VoidResult try_network_operation(F &&operation)
Error handling helper for network operations.
common::VoidResult check_stream_state(const Stream &stream, const std::string &operation_name="operation")
Stream state verification helper.
void log_error_context(const error_context &context)
Log error to stderr with context.
common::VoidResult try_open_operation(F &&operation)
Error handling helper for file open operations.
common::VoidResult check_file_exists(const std::filesystem::path &path)
File existence verification helper.
common::VoidResult try_encryption_operation(F &&operation)
Error handling helper for encryption operations.
common::VoidResult try_write_operation(F &&operation, logger_error_code default_error_code=logger_error_code::file_write_failed)
Error handling helper for write operations.
common::VoidResult check_condition(bool condition, logger_error_code error_code, const std::string &message)
Condition verification helper.
common::VoidResult ensure_directory_exists(const std::filesystem::path &dir)
Directory creation helper.
void safe_destructor_result_operation(const std::string &operation_name, F &&operation) noexcept
Safe operation with result for destructors.
logger_error_code
Error codes specific to the logger system.
common::VoidResult make_logger_void_result(logger_error_code code, const std::string &message="")
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.
Structured error context for debugging.
std::chrono::system_clock::time_point timestamp
error_context(logger_error_code error_code, std::string error_message, std::string op="", std::string file="", int line=0)
Construct error context with manual location information.
std::string to_string() const
Convert error context to a formatted string.