On Fri, 12 Dec 2025 at 10:59, Jonathan Wakely <cxx@kayari.org> wrote:


On Fri, 12 Dec 2025 at 10:12, 叶易安 via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
Consider this 2 exception outputs.

===== case A =====
terminate called after throwing an instance of 'network_error'
  what(): connection failed (104).

===== case B =====
terminate called after throwing an instance of 'network_error'
  what(): conection failed (with layer = transport, protocol = tcp, local_endpoint = 0.0.0.0:21798, remote_endpoint = 198.23.64.125:37720, error_code = 104, reason = "Connection reset by peer", status = "SYN ACK")

In user's perspective, the user/caller usually prefers an output like B. But currently almost all C++ 3rd-party libraries (who use exception rather then error_code/assert) provides something like A.

Maybe should we **encourage** people to carry more information in exceptions?

For case B you are much better off capturing the data in the exception object directly, not formatting it as a string.

i.e. instead of:

throw network_error("connection failed (with layer = {}, protocol = {}, local_endpoint = {}, remote_endpoint = {}, error_code = {}, reason = \"{}\", status = \"{}\"", layer, proto, lep, rep, ec, why, status);

you should do:

throw network_error("connection failed", layer, proto, lep, rep, ec, why, status);

The exception type should store those values and provide getters to access those values later. It can also use std::format internally to create a string that is stored and returned from network_error::what() (maybe by passing that string to a std::runtime_error base class, if it derives from that).