userver
C++ Async Framework
Toggle main menu visibility
Loading...
Searching...
No Matches
traceful_exception.hpp
Go to the documentation of this file.
1
#
pragma
once
2
3
/// @file userver/utils/traceful_exception.hpp
4
/// @brief @copybrief utils::TracefulException
5
6
#
include
<
exception
>
7
#
include
<
iterator
>
8
#
include
<
string
>
9
#
include
<
type_traits
>
10
11
#
include
<
fmt
/
format
.
h
>
12
#
include
<
boost
/
stacktrace
/
stacktrace_fwd
.
hpp
>
13
14
#
include
<
userver
/
compiler
/
select
.
hpp
>
15
#
include
<
userver
/
utils
/
fast_pimpl
.
hpp
>
16
17
USERVER_NAMESPACE_BEGIN
18
19
namespace
utils
{
20
21
/// @brief Base class implementing backtrace storage and message builder,
22
/// published only for documentation purposes, please inherit from
23
/// utils::TracefulException instead.
24
class
TracefulExceptionBase
{
25
public
:
26
enum
class
TraceMode {
27
kAlways,
28
kIfLoggingIsEnabled,
29
};
30
31
static
constexpr
size_t kInlineBufferSize = 100;
32
using
MemoryBuffer = fmt::basic_memory_buffer<
char
, kInlineBufferSize>;
33
34
TracefulExceptionBase();
35
36
explicit
TracefulExceptionBase(std::string_view what);
37
38
explicit
TracefulExceptionBase(TraceMode trace_mode);
39
40
TracefulExceptionBase(
TracefulExceptionBase
&&)
noexcept
;
41
virtual
~TracefulExceptionBase() = 0;
42
43
const
MemoryBuffer& MessageBuffer()
const
noexcept
;
44
const
boost::stacktrace::basic_stacktrace<>& Trace()
const
noexcept
;
45
46
/// Stream-like interface for message extension
47
template
<
typename
Exception,
typename
T>
48
requires
std::is_base_of_v<
TracefulExceptionBase
, std::remove_reference_t<Exception>>
49
friend
Exception&& operator<<(Exception&& ex,
const
T& data) {
50
fmt::format_to(std::back_inserter(ex.GetMessageBuffer()),
"{}"
, data);
51
ex.EnsureNullTerminated();
52
return
std::forward<Exception>(ex);
53
}
54
55
private
:
56
void
EnsureNullTerminated();
57
58
MemoryBuffer& GetMessageBuffer();
59
60
struct
Impl;
61
static
constexpr
std::size_t kSize =
sizeof
(MemoryBuffer) +
compiler
::
SelectSize
().For64Bit(24).For32Bit(12);
62
utils
::FastPimpl<Impl, kSize,
alignof
(
void
*)> impl_;
63
};
64
65
/// @ingroup userver_universal userver_base_classes
66
///
67
/// @brief Exception that remembers the backtrace at the point of its
68
/// construction
69
// NOLINTNEXTLINE(fuchsia-multiple-inheritance)
70
class
TracefulException
:
public
std::exception,
public
TracefulExceptionBase
{
71
public
:
72
using
TracefulExceptionBase
::TracefulExceptionBase;
73
74
const
char
* what()
const
noexcept
override
;
75
};
76
77
namespace
impl {
78
79
template
<
typename
PlainException>
80
// NOLINTNEXTLINE(fuchsia-multiple-inheritance)
81
class
ExceptionWithAttachedTrace
final
:
public
PlainException,
public
TracefulExceptionBase
{
82
public
:
83
explicit
ExceptionWithAttachedTrace(
const
PlainException& ex)
84
: PlainException(ex),
85
TracefulExceptionBase
(ex.what())
86
{}
87
};
88
89
template
<
typename
Exception>
90
requires
std::is_base_of_v<std::exception, Exception>
91
ExceptionWithAttachedTrace<Exception> AttachTraceToException(
const
Exception& ex) {
92
static_assert
(!std::is_base_of_v<
TracefulExceptionBase
, Exception>,
"This exception already contains trace"
);
93
return
ExceptionWithAttachedTrace<Exception>(ex);
94
}
95
96
}
// namespace impl
97
}
// namespace utils
98
99
USERVER_NAMESPACE_END
userver
utils
traceful_exception.hpp
Generated on
for userver by
Doxygen
1.17.0