-
Notifications
You must be signed in to change notification settings - Fork 45
/
Exception.cc
90 lines (76 loc) · 1.79 KB
/
Exception.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include <elle/Exception.hh>
#include <elle/assert.hh>
#include <elle/os/environ.hh>
#include <elle/serialization/Serializer.hh>
namespace elle
{
/*-------------.
| Construction |
`-------------*/
Exception::Exception(std::string const& message, int skip)
: Exception(Backtrace::current(1 + skip), message)
{}
Exception::Exception(Backtrace bt, std::string const& message)
: std::runtime_error(message)
, _backtrace(std::move(bt))
{}
Exception::~Exception() noexcept = default;
void
Exception::inner_exception(std::exception_ptr exception)
{
this->_inner_exception = exception;
}
/*--------------.
| Serialization |
`--------------*/
Exception::Exception(elle::serialization::SerializerIn& input)
: std::runtime_error(input.deserialize<std::string>("message"))
{}
void
Exception::serialize(elle::serialization::Serializer& s,
elle::Version const& version)
{
auto message = std::string{this->what()};
s.serialize("message", message);
}
/*--------.
| Helpers |
`--------*/
std::ostream&
operator <<(std::ostream& s, Exception const& e)
{
s << e.what();
if (os::getenv("ELLE_DEBUG_BACKTRACE", false))
s << e.backtrace();
return s;
}
std::string
exception_string(std::exception_ptr err)
{
return exception_string(err, std::current_exception());
}
std::string
exception_string(std::exception_ptr eptr, std::exception_ptr cur)
{
if (!eptr)
{
ELLE_ASSERT(cur);
eptr = cur;
}
if (!eptr)
throw Exception{"no current exception"};
try
{
std::rethrow_exception(eptr);
}
catch (std::exception const& e)
{
return e.what();
}
catch (...)
{
return "unknown exception type";
}
elle::unreachable();
}
}