2828
2929#include < concepts>
3030#include < cstdlib>
31- #include < exception>
3231#include < format>
3332#include < memory>
3433#include < source_location>
@@ -340,10 +339,10 @@ void FormatAndEmit(Logger& logger, LogLevel level, const std::source_location& l
340339 if (!logger.ShouldLog (level)) return ;
341340 try {
342341 Emit (logger, level, loc, std::format (fmt, std::forward<Args>(args)...));
343- } catch (const std::exception& ) {
344- // The only throws here are std::format_error / std::bad_alloc -- same recovery
345- // for both (drop, emit a fixed marker). Catch std::exception, not (...), so a
346- // non-std unwind like abi::__forced_unwind (thread cancellation) propagates .
342+ } catch (... ) {
343+ // Catch-all upholds the noexcept "logging never throws" guarantee: a
344+ // user-defined std::formatter may throw a non- std::exception type, and this
345+ // function is noexcept, so anything escaping here would call std::terminate .
347346 EmitFormatError (logger, level, loc);
348347 }
349348}
@@ -385,21 +384,22 @@ void Log(Logger& logger, LogLevel level,
385384// site and, for the default CerrLogger, the line it produces.
386385//
387386// ICEBERG_LOG_TRACE("entering scan for {}", table);
388- // 2026-06-16T10:59:41.186Z trace [12345] table_scan.cc:88] entering scan for db.t
387+ // 2026-06-16T10:59:41.186Z trace [12345] [ table_scan.cc:88] entering scan for db.t
389388// ICEBERG_LOG_DEBUG("cache miss key={}", key);
390- // 2026-06-16T10:59:41.186Z debug [12345] cache.cc:42] cache miss key=manifest-7
389+ // 2026-06-16T10:59:41.186Z debug [12345] [ cache.cc:42] cache miss key=manifest-7
391390// ICEBERG_LOG_INFO("loaded {} manifests in {} ms", n, ms);
392- // 2026-06-16T10:59:41.186Z info [12345] table_scan.cc:91] loaded 5 manifests in 12 ms
391+ // 2026-06-16T10:59:41.186Z info [12345] [table_scan.cc:91] loaded 5 manifests in 12
392+ // ms
393393// ICEBERG_LOG_WARN("retry {} after {}", attempt, err);
394- // 2026-06-16T10:59:41.186Z warn [12345] io.cc:51] retry 2 after timeout
394+ // 2026-06-16T10:59:41.186Z warn [12345] [ io.cc:51] retry 2 after timeout
395395// ICEBERG_LOG_ERROR("commit failed: {}", status);
396- // 2026-06-16T10:59:41.186Z error [12345] txn.cc:77] commit failed: conflict
396+ // 2026-06-16T10:59:41.186Z error [12345] [ txn.cc:77] commit failed: conflict
397397// ICEBERG_LOG_CRITICAL("metadata unreadable at {}", path);
398- // 2026-06-16T10:59:41.186Z critical [12345] meta.cc:30] metadata unreadable at
398+ // 2026-06-16T10:59:41.186Z critical [12345] [ meta.cc:30] metadata unreadable at
399399// s3://b/m.json
400400// ICEBERG_LOG_FATAL("unrecoverable: {}", reason); // emits, flushes, then
401401// std::abort()
402- // 2026-06-16T10:59:41.186Z fatal [12345] boot.cc:19] unrecoverable: bad config
402+ // 2026-06-16T10:59:41.186Z fatal [12345] [ boot.cc:19] unrecoverable: bad config
403403//
404404// Less common forms:
405405// ICEBERG_LOG(level, "level chosen at runtime: {}", x); // runtime severity
@@ -411,19 +411,22 @@ void Log(Logger& logger, LogLevel level,
411411// (ICEBERG_LOG_INFO("done")).
412412// ---------------------------------------------------------------------------
413413
414- // / \brief Compile-time severity floor: statements below this level are removed
415- // / entirely from the build (their format call sites and source_location literals
416- // / are never emitted). Defaults to keeping everything. ICEBERG_LOG_FATAL is never
417- // / gated by this floor -- its abort is always compiled in.
414+ // / \brief Compile-time severity floor: statements below this level are discarded
415+ // / via `if constexpr`, so no emit code runs and no format call / source_location
416+ // / is generated for them (the compiler is free to optimize the dead branch away).
417+ // / The statement must still be well-formed -- a bad format string or a
418+ // / non-formattable argument is a compile error even when the branch is discarded.
419+ // / Defaults to keeping everything. ICEBERG_LOG_FATAL is never gated by this floor
420+ // / -- its abort is always compiled in.
418421#ifndef ICEBERG_LOG_ACTIVE_LEVEL
419422# define ICEBERG_LOG_ACTIVE_LEVEL ::iceberg::LogLevel::kTrace
420423#endif
421424
422425// Internal: fixed-severity emit with compile-time floor then the authoritative
423426// Logger::ShouldLog (the single source of truth for runtime filtering), with
424- // formatting only on the taken path, never throwing. The catch handles
425- // std::exception (std::format_error / std::bad_alloc) -- not (...) -- so a non- std
426- // unwind such as abi::__forced_unwind (thread cancellation) still propagates .
427+ // formatting only on the taken path, never throwing. The catch-all upholds the
428+ // "logging never throws" guarantee even when a user-defined std::formatter throws
429+ // a non-std::exception type (a std::format_error/bad_alloc route to EmitFormatError) .
427430#define ICEBERG_INTERNAL_LOG (level_, FMT_ , ...) \
428431 do { \
429432 if constexpr ((level_) >= ICEBERG_LOG_ACTIVE_LEVEL ) { \
@@ -433,7 +436,7 @@ void Log(Logger& logger, LogLevel level,
433436 ::iceberg::internal::Emit (*_ib_logger, (level_), \
434437 ::std::source_location::current(), \
435438 ::std::format(FMT_ __VA_OPT__ (, ) __VA_ARGS__)); \
436- } catch (const std::exception& ) { \
439+ } catch (... ) { \
437440 ::iceberg::internal::EmitFormatError (*_ib_logger, (level_), \
438441 ::std::source_location::current()); \
439442 } \
@@ -466,7 +469,7 @@ void Log(Logger& logger, LogLevel level,
466469 ::iceberg::internal::Emit (*_ib_logger, ::iceberg::LogLevel::kFatal , \
467470 ::std::source_location::current (), \
468471 ::std::format(FMT_ __VA_OPT__ (, ) __VA_ARGS__)); \
469- } catch (const std::exception& ) { \
472+ } catch (... ) { \
470473 ::iceberg::internal::EmitFormatError (*_ib_logger, ::iceberg::LogLevel::kFatal , \
471474 ::std::source_location::current ()); \
472475 } \
@@ -487,7 +490,7 @@ void Log(Logger& logger, LogLevel level,
487490 ::iceberg::internal::Emit (*_ib_logger, _ib_lvl, \
488491 ::std::source_location::current (), \
489492 ::std::format(FMT_ __VA_OPT__ (, ) __VA_ARGS__)); \
490- } catch (const std::exception& ) { \
493+ } catch (... ) { \
491494 ::iceberg::internal::EmitFormatError (*_ib_logger, _ib_lvl, \
492495 ::std::source_location::current ()); \
493496 } \
@@ -509,7 +512,7 @@ void Log(Logger& logger, LogLevel level,
509512 ::iceberg::internal::Emit (_ib_logger, _ib_lvl, \
510513 ::std::source_location::current (), \
511514 ::std::format(FMT_ __VA_OPT__ (, ) __VA_ARGS__)); \
512- } catch (const std::exception& ) { \
515+ } catch (... ) { \
513516 ::iceberg::internal::EmitFormatError (_ib_logger, _ib_lvl, \
514517 ::std::source_location::current ()); \
515518 } \
@@ -531,7 +534,7 @@ void Log(Logger& logger, LogLevel level,
531534 ::iceberg::internal::Emit ( \
532535 *_ib_logger, _ib_lvl, ::std::source_location::current(), \
533536 ::iceberg::internal::VFormat((FMT_ )__VA_OPT__(, ) __VA_ARGS__)); \
534- } catch (const std::exception& ) { \
537+ } catch (... ) { \
535538 ::iceberg::internal::EmitFormatError (*_ib_logger, _ib_lvl, \
536539 ::std::source_location::current ()); \
537540 } \
0 commit comments