Skip to content

[CODE HEALTH] Fix clang-tidy bugprone-exception-escape in ostream exporters#4137

Open
jensecrest wants to merge 3 commits into
open-telemetry:mainfrom
jensecrest:clangtidy-bugproneexcesc-ostream
Open

[CODE HEALTH] Fix clang-tidy bugprone-exception-escape in ostream exporters#4137
jensecrest wants to merge 3 commits into
open-telemetry:mainfrom
jensecrest:clangtidy-bugproneexcesc-ostream

Conversation

@jensecrest
Copy link
Copy Markdown
Contributor

@jensecrest jensecrest commented Jun 7, 2026

Fixes #2053

Changes

Fixes 3 bugprone-exception-escape clang-tidy warnings in the ostream exporters by wrapping the throwing portions of Export in try/catch, guarded by #if OPENTELEMETRY_HAVE_EXCEPTIONS.

  • OStreamLogRecordExporter::Export in log_record_exporter.cc
  • OStreamSpanExporter::Export in span_exporter.cc
  • OStreamMetricExporter::Export in metric_exporter.cc

What the problem is

All three Export functions are marked noexcept (required by their base class interfaces), but contain operations that can throw:

  • sout_ << ...std::ostream::operator<< can throw std::ios_base::failure if exceptions are enabled on the stream
  • std::string(char*, len) construction — can throw std::bad_alloc
  • Helper functions like printAttributes, printEvents, printInstrumentationInfoMetricData — all use ostream internally

If any of these throw inside a noexcept function, the program calls std::terminate() — a crash.

Why try/catch is the minimal fix

  • We cannot remove noexcept — it's on the pure virtual base class interfaces (LogRecordExporter, SpanExporter, PushMetricExporter). Changing it would be an API/ABI break.
  • We cannot replace the throwing operations with non-throwing alternatives — there is no non-throwing version of operator<< or std::string construction. The entire purpose of these functions is to write to an ostream.
  • try/catch is the established pattern in this codebase — see PeriodicExportingMetricReader::CollectAndExportOnce() in periodic_exporting_metric_reader.cc, which uses the same #if OPENTELEMETRY_HAVE_EXCEPTIONS / try / catch structure.

What the change does

Wraps the throwing portion of each Export function in try/catch, guarded by #if OPENTELEMETRY_HAVE_EXCEPTIONS (the project's standard guard for builds with exceptions disabled via -fno-exceptions). On exception, the error is logged via OTEL_INTERNAL_LOG_ERROR and kFailure is returned.

What the change does NOT do

  • Does not change function signatures, return types, or the noexcept specifier
  • Does not change behavior on the happy path — when no exception occurs, the functions execute identically and return kSuccess
  • Does not change the error-path return for the shutdown check (still returns kFailure before the try block)
  • On the exception path: changes behavior from std::terminate() (crash) to logging an error and returning kFailure (graceful degradation)

For significant contributions please make sure you have completed the following items:

  • CHANGELOG.md updated for non-trivial changes
  • Unit tests have been added
  • Changes in public API reviewed

AI

Assisted-by: This contribution was prepared with the assistance of an AI development tool.

@jensecrest jensecrest requested a review from a team as a code owner June 7, 2026 14:02
@codecov
Copy link
Copy Markdown

codecov Bot commented Jun 7, 2026

Codecov Report

❌ Patch coverage is 75.78947% with 23 lines in your changes missing coverage. Please review.
✅ Project coverage is 81.89%. Comparing base (af27cc9) to head (6633f3e).

Files with missing lines Patch % Lines
exporters/ostream/src/log_record_exporter.cc 81.64% 9 Missing ⚠️
exporters/ostream/src/metric_exporter.cc 22.23% 7 Missing ⚠️
exporters/ostream/src/span_exporter.cc 81.09% 7 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #4137      +/-   ##
==========================================
- Coverage   82.02%   81.89%   -0.13%     
==========================================
  Files         385      385              
  Lines       16071    16095      +24     
==========================================
- Hits        13181    13179       -2     
- Misses       2890     2916      +26     
Files with missing lines Coverage Δ
exporters/ostream/src/metric_exporter.cc 86.37% <22.23%> (-4.73%) ⬇️
exporters/ostream/src/span_exporter.cc 81.91% <81.09%> (-6.75%) ⬇️
exporters/ostream/src/log_record_exporter.cc 80.52% <81.64%> (-9.33%) ⬇️

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Code health] clang-tidy cleanup

1 participant