10#include <fmt/format.h>
11#include <boost/stacktrace/stacktrace_fwd.hpp>
13#include <userver/compiler/select.hpp>
14#include <userver/utils/fast_pimpl.hpp>
16USERVER_NAMESPACE_BEGIN
25 enum class TraceMode {
30 static constexpr size_t kInlineBufferSize = 100;
33 TracefulExceptionBase();
35 explicit TracefulExceptionBase(std::string_view what);
37 explicit TracefulExceptionBase(TraceMode trace_mode);
40 virtual ~TracefulExceptionBase() = 0;
42 const MemoryBuffer& MessageBuffer()
const noexcept;
43 const boost::stacktrace::basic_stacktrace<>& Trace()
const noexcept;
46 template <
typename Exception,
typename T>
47 friend typename std::enable_if<
49 typename std::remove_reference<Exception>::type>::value,
51 operator<<(Exception&& ex,
const T& data) {
52 fmt::format_to(std::back_inserter(ex.GetMessageBuffer()),
"{}", data);
53 ex.EnsureNullTerminated();
54 return std::forward<Exception>(ex);
58 void EnsureNullTerminated();
60 MemoryBuffer& GetMessageBuffer();
63 static constexpr std::size_t kSize =
65 utils::FastPimpl<Impl, kSize,
alignof(
void*)> impl_;
77 const char* what()
const noexcept override;
82template <
typename PlainException>
84class ExceptionWithAttachedTrace
final :
public PlainException,
87 explicit ExceptionWithAttachedTrace(
const PlainException& ex)
91template <
typename Exception>
92std::enable_if_t<std::is_base_of<std::exception, Exception>::value,
93 ExceptionWithAttachedTrace<Exception>>
94AttachTraceToException(
const Exception& ex) {
96 "This exception already contains trace");
97 return ExceptionWithAttachedTrace<Exception>(ex);