Skip to content

misc: inherit publicly from std::exception#30027

Merged
rockwotj merged 1 commit intoredpanda-data:devfrom
WillemKauf:exception_print_fix
Apr 1, 2026
Merged

misc: inherit publicly from std::exception#30027
rockwotj merged 1 commit intoredpanda-data:devfrom
WillemKauf:exception_print_fix

Conversation

@WillemKauf
Copy link
Copy Markdown
Contributor

Several exception classes used private inheritance from std::exception (the default for class). This prevents catch(const std::exception&) from matching, and causes exception_ptr formatting to print only the type name instead of the full what() message.

I discovered this when trying to debug an ERROR log line which wasn't very helpful:

ERROR 2026-03-31 20:40:20,925 [shard 1:ctr ] cloud_io - multipart_upload.cc:175 - Multipart upload completion failed, aborting: cloud_storage_clients::rest_error_response

from

auto ex = fut.get_exception();
vlogl(
_logger,
ssx::is_shutdown_exception(ex) ? ss::log_level::warn
: ss::log_level::error,
"Multipart upload completion failed, aborting: {}",
ex);

Backports Required

  • none - not a bug fix
  • none - this is a backport
  • none - issue does not exist in previous branches
  • none - papercut/not impactful enough to backport
  • v26.1.x
  • v25.3.x
  • v25.2.x

Release Notes

  • none

Several exception classes used private inheritance from `std::exception`
(the default for `class`). This prevents catch(const std::exception&)
from matching and causes `exception_ptr` formatting to print only the
type name instead of the full `what()` message.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes several custom exception types that were inadvertently inheriting privately from std::exception (the default for class), which prevented them from being caught via catch(const std::exception&) and reduced the usefulness of exception formatting/logging that relies on what().

Changes:

  • Switches multiple exception classes to public std::exception inheritance so they behave as proper std::exception subtypes.
  • Improves debuggability/observability by enabling standard exception handling patterns and exception_ptr-based reporting to access what() where implemented.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/v/wasm/parser/leb128.h Make decode_exception publicly derive from std::exception.
src/v/rpc/exceptions.h Make request_timeout_exception publicly derive from std::exception.
src/v/net/batched_output_stream.h Make batched_output_stream_closed publicly derive from std::exception.
src/v/iceberg/transform_utils.h Make partition_spec_field_error publicly derive from std::exception.
src/v/datalake/partition_key_path.h Make partition_key_error publicly derive from std::exception.
src/v/cloud_storage_clients/s3_error.h Make rest_error_response publicly derive from std::exception.
src/v/cloud_storage_clients/abs_error.h Make abs_rest_error_response publicly derive from std::exception.

@vbotbuildovich
Copy link
Copy Markdown
Collaborator

CI test results

test results on build#82593
test_class test_method test_arguments test_kind job_url test_status passed reason test_history
EndToEndShadowIndexingTest test_reset {"cloud_storage_type": 1} integration https://buildkite.com/redpanda/redpanda/builds/82593#019d4713-929c-4bb2-afc4-e8d62660d3b7 FLAKY 10/11 Test PASSES after retries.No significant increase in flaky rate(baseline=0.0000, p0=1.0000, reject_threshold=0.0100. adj_baseline=0.1000, p1=0.3487, trust_threshold=0.5000) https://redpanda.metabaseapp.com/dashboard/87-tests?tab=142-dt-individual-test-history&test_class=EndToEndShadowIndexingTest&test_method=test_reset
src/v/cloud_topics/level_zero/gc/tests/level_zero_gc_test src/v/cloud_topics/level_zero/gc/tests/level_zero_gc_test unit https://buildkite.com/redpanda/redpanda/builds/82593#019d46f8-d499-46b3-b606-9455494831bb FAIL 0/1

@rockwotj rockwotj merged commit f568a15 into redpanda-data:dev Apr 1, 2026
24 checks passed
@dotnwat
Copy link
Copy Markdown
Member

dotnwat commented Apr 1, 2026

This prevents catch(const std::exception&) from matching

wut? that's unexpected. do you have a reference to the rule?

@dotnwat
Copy link
Copy Markdown
Member

dotnwat commented Apr 1, 2026

This prevents catch(const std::exception&) from matching

wut? that's unexpected. do you have a reference to the rule?

i wonder if this should be a clang-tidy thing. it seems like getting a warning/compilation error would make sense if you try to do something that can never happen!

@rockwotj
Copy link
Copy Markdown
Contributor

rockwotj commented Apr 2, 2026

This prevents catch(const std::exception&) from matching

wut? that's unexpected. do you have a reference to the rule?

i wonder if this should be a clang-tidy thing. it seems like getting a warning/compilation error would make sense if you try to do something that can never happen!

I think https://clang.llvm.org/extra/clang-tidy/checks/bugprone/std-exception-baseclass.html catches this

@WillemKauf
Copy link
Copy Markdown
Contributor Author

wut? that's unexpected. do you have a reference to the rule?

Do you enjoy reading the C++ standard?

https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4950.pdf#page=466

A handler is a match for an exception object of type E if
—(3.1) The handler is of type cv T or cv T& and E and T are the same type (ignoring the top-level cv-qualifier s),
or
—(3.2) the handler is of type cv T or cv T& and T is an unambiguous public base class of E, or
—(3.3) the handler is of type cv T or const T& where T is a pointer or pointer-to-member type and E is a
pointer or pointer-to-member type that can be converted to T by one or more of
——(3.3.1) a standard pointer conversion (7.3.12) not involving conversions to pointers to private or protected
or ambiguous classes
——(3.3.2) a function pointer conversion (7.3.14)
——(3.3.3) a qualification conversion (7.3.6), or
—(3.4) the handler is of type cv T or const T& where T is a pointer or pointer-to-member type and E is
std::nullptr_t.

3.2 is the relevant bullet point here.

@WillemKauf
Copy link
Copy Markdown
Contributor Author

I think https://clang.llvm.org/extra/clang-tidy/checks/bugprone/std-exception-baseclass.html catches this

Nice. Should we error on it?

@WillemKauf
Copy link
Copy Markdown
Contributor Author

Ah, only available in clang-tidy 21 and above. Soon

@dotnwat
Copy link
Copy Markdown
Member

dotnwat commented Apr 2, 2026

Ah, only available in clang-tidy 21 and above. Soon

#30012

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

Labels

area/redpanda area/wasm WASM Data Transforms

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants