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<
50 operator<<(Exception&& ex,
const T& data) {
51 fmt::format_to(std::back_inserter(ex.GetMessageBuffer()),
"{}", data);
52 ex.EnsureNullTerminated();
53 return std::forward<Exception>(ex);
57 void EnsureNullTerminated();
59 MemoryBuffer& GetMessageBuffer();
63 utils::FastPimpl<Impl, kSize,
alignof(
void*)> impl_;
75 const char* what()
const noexcept override;
80template <
typename PlainException>
84 explicit ExceptionWithAttachedTrace(
const PlainException& ex)
88template <
typename Exception>
89std::enable_if_t<std::is_base_of<std::exception, Exception>::value, ExceptionWithAttachedTrace<Exception>>
90AttachTraceToException(
const Exception& ex) {
91 static_assert(!std::is_base_of<
TracefulExceptionBase, Exception>::value,
"This exception already contains trace");
92 return ExceptionWithAttachedTrace<Exception>(ex);