proxygen
folly::exception_wrapper Class Referencefinal

#include <ExceptionWrapper.h>

Classes

struct  AnyException
 
struct  arg_type_
 
struct  arg_type_< Ret(*)(...)>
 
struct  arg_type_< Ret(*)(Arg)>
 
struct  arg_type_< Ret(...)>
 
struct  arg_type_< Ret(Arg)>
 
struct  arg_type_< Ret(Class::*)(...) const >
 
struct  arg_type_< Ret(Class::*)(...)>
 
struct  arg_type_< Ret(Class::*)(Arg) const >
 
struct  arg_type_< Ret(Class::*)(Arg)>
 
struct  Buffer
 
struct  ExceptionPtr
 
struct  ExceptionTypeOf
 
struct  HandleReduce
 
struct  HandleStdExceptReduce
 
struct  InPlace
 
struct  InSituTag
 
struct  IsRegularExceptionType
 
struct  OnHeapTag
 
struct  SharedPtr
 
struct  ThrownTag
 
struct  Unknown
 
struct  VTable
 

Public Member Functions

 exception_wrapper () noexcept
 
 exception_wrapper (exception_wrapper &&that) noexcept
 
 exception_wrapper (exception_wrapper const &that) noexcept
 
exception_wrapperoperator= (exception_wrapper &&that) noexcept
 
exception_wrapperoperator= (exception_wrapper const &that) noexcept
 
 ~exception_wrapper ()
 
 exception_wrapper (std::exception_ptr ptr) noexcept
 
template<class Ex >
 exception_wrapper (std::exception_ptr ptr, Ex &ex) noexcept
 
template<class Ex , class Ex_ = _t<std::decay<Ex>>>
 exception_wrapper (Ex &&ex)
 
template<class Ex , class Ex_ = _t<std::decay<Ex>>, _t< std::enable_if< static_cast< bool >(IsRegularExceptionType< Ex_ >::value), long >> = __LINE__>
 exception_wrapper (in_place_t, Ex &&ex)
 
template<class Ex , typename... As, _t< std::enable_if< static_cast< bool >(IsRegularExceptionType< Ex >::value), long >> = __LINE__>
 exception_wrapper (in_place_type_t< Ex >, As &&...as)
 
void swap (exception_wrapper &that) noexcept
 Swaps the value of *this with the value of that More...
 
 operator bool () const noexcept
 
bool operator! () const noexcept
 
void reset ()
 
bool has_exception_ptr () const noexcept
 
std::exception * get_exception () noexcept
 
std::exception const * get_exception () const noexcept
 
template<typename Ex >
Ex * get_exception () noexcept
 
template<typename Ex >
Ex const * get_exception () const noexcept
 
std::exception_ptr const & to_exception_ptr () noexcept
 
std::exception_ptr to_exception_ptr () const noexcept
 
std::type_info const & type () const noexcept
 
folly::fbstring what () const
 
folly::fbstring class_name () const
 
template<class Ex >
bool is_compatible_with () const noexcept
 
void throw_exception () const
 
template<class Ex >
void throw_with_nested (Ex &&ex) const
 
template<class Ex = void const, class Fn >
bool with_exception (Fn fn)
 
template<class Ex = void const, class Fn >
bool with_exception (Fn fn) const
 
template<class... CatchFns>
void handle (CatchFns...fns)
 
template<class... CatchFns>
void handle (CatchFns...fns) const
 
template<class Ex , class Ex_, FOLLY_REQUIRES_DEF(Conjunction< exception_wrapper::IsStdException< Ex_ >,exception_wrapper::IsRegularExceptionType< Ex_ >>::value) >
 exception_wrapper (Ex &&ex)
 

Static Public Member Functions

static exception_wrapper from_exception_ptr (std::exception_ptr const &eptr) noexcept
 
static std::type_info const & none () noexcept
 
static std::type_info const & unknown () noexcept
 

Private Types

template<class Fn >
using arg_type = _t< arg_type_< Fn >>
 
template<class Ex >
using IsStdException = std::is_base_of< std::exception, _t< std::decay< Ex >>>
 
template<bool B, class T >
using AddConstIf = exception_wrapper_detail::AddConstIf< B, T >
 
template<class CatchFn >
using IsCatchAll = std::is_same< arg_type< _t< std::decay< CatchFn >>>, AnyException >
 
template<class T >
using PlacementOf = _t< std::conditional< !IsStdException< T >::value, ThrownTag, _t< std::conditional< sizeof(T)<=sizeof(Buffer::Storage)&&alignof(T)<=alignof(Buffer::Storage)&&noexcept(T(std::declval< T && >()))&&noexcept(T(std::declval< T const & >())), InSituTag, OnHeapTag >>>>
 

Private Member Functions

template<class Ex , typename... As>
 exception_wrapper (ThrownTag, in_place_type_t< Ex >, As &&...as)
 
template<class Ex , typename... As>
 exception_wrapper (OnHeapTag, in_place_type_t< Ex >, As &&...as)
 
template<class Ex , typename... As>
 exception_wrapper (InSituTag, in_place_type_t< Ex >, As &&...as)
 

Static Private Member Functions

static void onNoExceptionError (char const *name)
 
template<class Ret , class... Args>
static Ret noop_ (Args...)
 
static std::type_info const * uninit_type_ (exception_wrapper const *)
 
static std::exception const * as_exception_or_null_ (std::exception const &ex)
 
static std::exception const * as_exception_or_null_ (AnyException)
 
template<class This , class... CatchFns>
static void handle_ (std::false_type, This &this_, CatchFns &...fns)
 
template<class This , class... CatchFns>
static void handle_ (std::true_type, This &this_, CatchFns &...fns)
 
template<class Ex , class This , class Fn >
static bool with_exception_ (This &this_, Fn fn_)
 

Private Attributes

union {
   Buffer   buff_ {}
 
   ExceptionPtr   eptr_
 
   SharedPtr   sptr_
 
}; 
 
VTable const * vptr_ {&uninit_}
 

Static Private Attributes

static VTable const uninit_
 

Detailed Description

Throwing exceptions can be a convenient way to handle errors. Storing exceptions in an exception_ptr makes it easy to handle exceptions in a different thread or at a later time. exception_ptr can also be used in a very generic result/exception wrapper.

However, there are some issues with throwing exceptions and std::exception_ptr. These issues revolve around throw being expensive, particularly in a multithreaded environment (see ExceptionWrapperBenchmark.cpp).

Imagine we have a library that has an API which returns a result/exception wrapper. Let's consider some approaches for implementing this wrapper. First, we could store a std::exception. This approach loses the derived exception type, which can make exception handling more difficult for users that prefer rethrowing the exception. We could use a folly::dynamic for every possible type of exception. This is not very flexible - adding new types of exceptions requires a change to the result/exception wrapper. We could use an exception_ptr. However, constructing an exception_ptr as well as accessing the error requires a call to throw. That means that there will be two calls to throw in order to process the exception. For performance sensitive applications, this may be unacceptable.

exception_wrapper is designed to handle exception management for both convenience and high performance use cases. make_exception_wrapper is templated on derived type, allowing us to rethrow the exception properly for users that prefer convenience. These explicitly named exception types can therefore be handled without any peformance penalty. exception_wrapper is also flexible enough to accept any type. If a caught exception is not of an explicitly named type, then std::exception_ptr is used to preserve the exception state. For performance sensitive applications, the accessor methods can test or extract a pointer to a specific exception type with very little overhead.

Example usage:
exception_wrapper globalExceptionWrapper;
// Thread1
void doSomethingCrazy() {
int rc = doSomethingCrazyWithLameReturnCodes();
if (rc == NAILED_IT) {
globalExceptionWrapper = exception_wrapper();
} else if (rc == FACE_PLANT) {
globalExceptionWrapper = make_exception_wrapper<FacePlantException>();
} else if (rc == FAIL_WHALE) {
globalExceptionWrapper = make_exception_wrapper<FailWhaleException>();
}
}
// Thread2: Exceptions are ok!
void processResult() {
try {
globalExceptionWrapper.throw_exception();
} catch (const FacePlantException& e) {
LOG(ERROR) << "FACEPLANT!";
} catch (const FailWhaleException& e) {
LOG(ERROR) << "FAILWHALE!";
}
}
// Thread2: Exceptions are bad!
void processResult() {
globalExceptionWrapper.handle(
[&](FacePlantException& faceplant) {
LOG(ERROR) << "FACEPLANT";
},
[&](FailWhaleException& failwhale) {
LOG(ERROR) << "FAILWHALE!";
},
[](...) {
LOG(FATAL) << "Unrecognized exception";
});
}

Definition at line 162 of file ExceptionWrapper.h.

Member Typedef Documentation

template<bool B, class T >
using folly::exception_wrapper::AddConstIf = exception_wrapper_detail::AddConstIf<B, T>
private

Definition at line 211 of file ExceptionWrapper.h.

template<class Fn >
using folly::exception_wrapper::arg_type = _t<arg_type_<Fn>>
private

Definition at line 173 of file ExceptionWrapper.h.

template<class CatchFn >
using folly::exception_wrapper::IsCatchAll = std::is_same<arg_type<_t<std::decay<CatchFn>>>, AnyException>
private

Definition at line 214 of file ExceptionWrapper.h.

template<class Ex >
using folly::exception_wrapper::IsStdException = std::is_base_of<std::exception, _t<std::decay<Ex>>>
private

Definition at line 209 of file ExceptionWrapper.h.

template<class T >
using folly::exception_wrapper::PlacementOf = _t<std::conditional< !IsStdException<T>::value, ThrownTag, _t<std::conditional< sizeof(T) <= sizeof(Buffer::Storage) && alignof(T) <= alignof(Buffer::Storage) && noexcept(T(std::declval<T&&>())) && noexcept(T(std::declval<T const&>())), InSituTag, OnHeapTag>>>>
private

Definition at line 251 of file ExceptionWrapper.h.

Constructor & Destructor Documentation

template<class Ex , typename... As>
folly::exception_wrapper::exception_wrapper ( ThrownTag  ,
in_place_type_t< Ex >  ,
As &&...  as 
)
inlineprivate

Definition at line 280 of file ExceptionWrapper-inl.h.

References folly::gen::as(), folly::exception_wrapper::ExceptionPtr::ops_, and vptr_.

284  : eptr_{std::make_exception_ptr(Ex(std::forward<As>(as)...)),
285  reinterpret_cast<std::uintptr_t>(std::addressof(typeid(Ex))) + 1u},
Collect as()
Definition: Base.h:811
template<class Ex , typename... As>
folly::exception_wrapper::exception_wrapper ( OnHeapTag  ,
in_place_type_t< Ex >  ,
As &&...  as 
)
inlineprivate

Definition at line 289 of file ExceptionWrapper-inl.h.

References folly::gen::as(), folly::exception_wrapper::SharedPtr::ops_, and vptr_.

293  : sptr_{std::make_shared<SharedPtr::Impl<Ex>>(std::forward<As>(as)...)},
Collect as()
Definition: Base.h:811
template<class Ex , typename... As>
folly::exception_wrapper::exception_wrapper ( InSituTag  ,
in_place_type_t< Ex >  ,
As &&...  as 
)
inlineprivate

Definition at line 297 of file ExceptionWrapper-inl.h.

References folly::gen::as(), and vptr_.

301  : buff_{in_place_type<Ex>, std::forward<As>(as)...},
static constexpr VTable const ops_
Collect as()
Definition: Base.h:811
folly::exception_wrapper::exception_wrapper ( )
inlinenoexcept
folly::exception_wrapper::exception_wrapper ( exception_wrapper &&  that)
inlinenoexcept

Move-constructs an exception_wrapper

Postcondition
*this contains the value of that prior to the move
that.type() == none()

Definition at line 304 of file ExceptionWrapper-inl.h.

References vptr_.

305  : exception_wrapper{} {
306  (vptr_ = that.vptr_)->move_(&that, this); // Move into *this, won't throw
307 }
folly::exception_wrapper::exception_wrapper ( exception_wrapper const &  that)
inlinenoexcept

Copy-constructs an exception_wrapper

Postcondition
*this contains a copy of that, and that is unmodified
type() == that.type()

Definition at line 309 of file ExceptionWrapper-inl.h.

References folly::exception_wrapper::VTable::copy_, and vptr_.

311  : exception_wrapper{} {
312  that.vptr_->copy_(&that, this); // Copy into *this, won't throw
313  vptr_ = that.vptr_;
314 }
folly::exception_wrapper::~exception_wrapper ( )
inline

Definition at line 331 of file ExceptionWrapper-inl.h.

References reset().

Referenced by folly::Try< void >::emplaceException(), and folly::Try< void >::operator=().

331  {
332  reset();
333 }
folly::exception_wrapper::exception_wrapper ( std::exception_ptr  ptr)
explicitnoexcept
Precondition
ptr is empty, or it holds a reference to an exception that is not derived from std::exception.
Postcondition
!ptr || bool(*this)
hasThrownException() == true
type() == unknown()

Definition at line 77 of file ExceptionWrapper.cpp.

References folly::DFATAL, folly::gen::move, and ptr.

78  : exception_wrapper{} {
79  if (ptr) {
80  if (auto e = get_std_exception_(ptr)) {
81  LOG(DFATAL)
82  << "Performance error: Please construct exception_wrapper with a "
83  "reference to the std::exception along with the "
84  "std::exception_ptr.";
85  *this = exception_wrapper{std::move(ptr), *e};
86  } else {
87  Unknown uk;
88  *this = exception_wrapper{ptr, uk};
89  }
90  }
91 }
void * ptr
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
template<class Ex >
folly::exception_wrapper::exception_wrapper ( std::exception_ptr  ptr,
Ex &  ex 
)
inlinenoexcept
Precondition
ptr holds a reference to ex.
Postcondition
hasThrownException() == true
bool(*this)
type() == typeid(ex)

Definition at line 336 of file ExceptionWrapper-inl.h.

References folly::exception_wrapper::ExceptionPtr::as_int_(), eptr_, folly::exception_wrapper::ExceptionPtr::ops_, ptr, folly::exception_wrapper::ExceptionPtr::ptr_, and vptr_.

340  assert(eptr_.ptr_);
341 }
void * ptr
static std::uintptr_t as_int_(std::exception_ptr const &ptr, std::exception const &e) noexcept
template<class Ex , class Ex_ = _t<std::decay<Ex>>>
folly::exception_wrapper::exception_wrapper ( Ex &&  ex)
Precondition
typeid(ex) == typeid(typename decay<Ex>type)
Postcondition
bool(*this)
hasThrownException() == false
type() == typeid(ex)
Note
Exceptions of types derived from std::exception can be implicitly converted to an exception_wrapper.
template<class Ex , class Ex_, FOLLY_REQUIRES_DEF(exception_wrapper::IsRegularExceptionType< Ex_ >::value) >
folly::exception_wrapper::exception_wrapper ( in_place_t  ,
Ex &&  ex 
)
inline
Precondition
typeid(ex) == typeid(typename decay<Ex>type)
Postcondition
bool(*this)
hasThrownException() == false
type() == typeid(ex)
Note
Exceptions of types not derived from std::exception can still be used to construct an exception_wrapper, but you must specify folly::in_place as the first parameter.

Definition at line 369 of file ExceptionWrapper-inl.h.

References folly::exception_wrapper_detail::dont_slice(), and FOLLY_REQUIRES_DEF.

371  PlacementOf<Ex_>{},
372  in_place_type<Ex_>,
373  exception_wrapper_detail::dont_slice(std::forward<Ex>(ex))} {}
template<class Ex , typename... As, FOLLY_REQUIRES_DEF(exception_wrapper::IsRegularExceptionType< Ex >::value) >
folly::exception_wrapper::exception_wrapper ( in_place_type_t< Ex >  ,
As &&...  as 
)
inline

Definition at line 379 of file ExceptionWrapper-inl.h.

References folly::gen::as().

380  : exception_wrapper{PlacementOf<Ex>{},
381  in_place_type<Ex>,
382  std::forward<As>(as)...} {}
Collect as()
Definition: Base.h:811
template<class Ex , class Ex_, FOLLY_REQUIRES_DEF(Conjunction< exception_wrapper::IsStdException< Ex_ >,exception_wrapper::IsRegularExceptionType< Ex_ >>::value) >
folly::exception_wrapper::exception_wrapper ( Ex &&  ex)
inline

Definition at line 359 of file ExceptionWrapper-inl.h.

References folly::exception_wrapper_detail::dont_slice(), and FOLLY_REQUIRES_DEF.

361  PlacementOf<Ex_>{},
362  in_place_type<Ex_>,
363  exception_wrapper_detail::dont_slice(std::forward<Ex>(ex))} {}

Member Function Documentation

std::exception const * folly::exception_wrapper::as_exception_or_null_ ( std::exception const &  ex)
inlinestaticprivate
std::exception const * folly::exception_wrapper::as_exception_or_null_ ( AnyException  )
inlinestaticprivate

Definition at line 89 of file ExceptionWrapper-inl.h.

References folly::kMicrosoftAbiVer.

90  {
91  return nullptr;
92 }
folly::fbstring folly::exception_wrapper::class_name ( ) const
inline
Returns
If !*this, the empty string; otherwise, if type() == unknown(), the string "\<unknown exception\>"; otherwise, the result of type().name() after demangling.

Definition at line 454 of file ExceptionWrapper-inl.h.

References folly::demangle(), none(), type(), and unknown().

Referenced by TEST(), and what().

454  {
455  auto& ti = type();
456  return ti == none()
457  ? ""
458  : ti == unknown() ? "<unknown exception>" : folly::demangle(ti);
459 }
static std::type_info const & unknown() noexcept
static std::type_info const & none() noexcept
std::type_info const & type() const noexcept
fbstring demangle(const char *name)
Definition: Demangle.cpp:111
exception_wrapper folly::exception_wrapper::from_exception_ptr ( std::exception_ptr const &  eptr)
staticnoexcept
std::exception * folly::exception_wrapper::get_exception ( )
inlinenoexcept
Returns
a pointer to the std::exception held by *this, if it holds one; otherwise, returns nullptr.
Note
This function does not mutate the exception_wrapper object.
This function never causes an exception to be thrown.

Definition at line 406 of file ExceptionWrapper-inl.h.

References folly::exception_wrapper::VTable::get_exception_, and vptr_.

Referenced by fizz::server::detail::processEvent(), and what().

406  {
407  return const_cast<std::exception*>(vptr_->get_exception_(this));
408 }
std::exception const *(* get_exception_)(exception_wrapper const *)
std::exception const * folly::exception_wrapper::get_exception ( ) const
inlinenoexcept

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Definition at line 409 of file ExceptionWrapper-inl.h.

References folly::exception_wrapper::VTable::get_exception_, and vptr_.

409  {
410  return vptr_->get_exception_(this);
411 }
std::exception const *(* get_exception_)(exception_wrapper const *)
template<typename Ex >
Ex * folly::exception_wrapper::get_exception ( )
inlinenoexcept
Returns
a pointer to the Ex held by *this, if it holds an object whose type From permits std::is_convertible<From*, Ex*>; otherwise, returns nullptr.
Note
This function does not mutate the exception_wrapper object.
This function may cause an exception to be thrown and immediately caught internally, affecting runtime performance.

Definition at line 414 of file ExceptionWrapper-inl.h.

References object, and with_exception().

414  {
415  Ex* object{nullptr};
416  with_exception([&](Ex& ex) { object = &ex; });
417  return object;
418 }
void * object
Definition: AtFork.cpp:32
template<typename Ex >
Ex const * folly::exception_wrapper::get_exception ( ) const
inlinenoexcept

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Definition at line 421 of file ExceptionWrapper-inl.h.

References object, and with_exception().

421  {
422  Ex const* object{nullptr};
423  with_exception([&](Ex const& ex) { object = &ex; });
424  return object;
425 }
void * object
Definition: AtFork.cpp:32
template<class... CatchFns>
void folly::exception_wrapper::handle ( CatchFns...  fns)
inline

Handle the wrapped expression as if with a series of catch clauses, propagating the exception if no handler matches.

Example
exception_wrapper ew{std::runtime_error("goodbye cruel world")};
ew.handle(
[&](std::logic_error const& e) {
LOG(DFATAL) << "ruh roh";
ew.throw_exception(); // rethrow the active exception without
// slicing it. Will not be caught by other
// handlers in this call.
},
[&](std::exception const& e) {
LOG(ERROR) << ew.what();
});
In the above example, any exception not derived from std::exception will be propagated. To specify a catch-all clause, pass a lambda that takes a C-style elipses, as in:
ew.handle(/*...* /, [](...) { /* handle unknown exception */ } )
Precondition
!*this
Template Parameters
CatchFns...A pack of unary monomorphic function object types.
Parameters
fnsA pack of unary monomorphic function objects to be treated as an ordered list of potential exception handlers.
Note
The handlers may or may not be invoked with an active exception. Do not try to rethrow the exception with throw; from within your handler – that is, a throw expression with no operand. This may cause your process to terminate. (It is perfectly ok to throw from a handler so long as you specify the exception to throw, as in throw e;.)

Definition at line 659 of file ExceptionWrapper-inl.h.

References handle_(), and onNoExceptionError().

Referenced by fizz::client::AsyncFizzClientT< SM >::deliverHandshakeError(), and TEST().

659  {
660  using AllStdEx =
661  exception_wrapper_detail::AllOf<IsStdException, arg_type<CatchFns>...>;
662  if (!*this) {
663  onNoExceptionError(__func__);
664  }
665  this->handle_(AllStdEx{}, *this, fns...);
666 }
static void onNoExceptionError(char const *name)
static void handle_(std::false_type, This &this_, CatchFns &...fns)
template<class... CatchFns>
void folly::exception_wrapper::handle ( CatchFns...  fns) const
inline

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Definition at line 668 of file ExceptionWrapper-inl.h.

References handle_(), and onNoExceptionError().

668  {
669  using AllStdEx =
670  exception_wrapper_detail::AllOf<IsStdException, arg_type<CatchFns>...>;
671  if (!*this) {
672  onNoExceptionError(__func__);
673  }
674  this->handle_(AllStdEx{}, *this, fns...);
675 }
static void onNoExceptionError(char const *name)
static void handle_(std::false_type, This &this_, CatchFns &...fns)
template<class This , class... CatchFns>
void folly::exception_wrapper::handle_ ( std::false_type  ,
This &  this_,
CatchFns &...  fns 
)
inlinestaticprivate

Definition at line 586 of file ExceptionWrapper-inl.h.

References folly::exception_wrapper_detail::fold(), handled, and value.

Referenced by handle(), and with_exception_().

586  {
587  bool handled = false;
588  auto impl = exception_wrapper_detail::fold(
589  HandleReduce<std::is_const<This>::value>{&handled},
590  [&] { this_.throw_exception(); },
591  fns...);
592  impl();
593 }
volatile bool handled
static const char *const value
Definition: Conv.cpp:50
FOLLY_ALWAYS_INLINE FOLLY_ATTR_VISIBILITY_HIDDEN auto fold(Fn &&, A &&a)
template<class This , class... CatchFns>
void folly::exception_wrapper::handle_ ( std::true_type  ,
This &  this_,
CatchFns &...  fns 
)
inlinestaticprivate

Definition at line 599 of file ExceptionWrapper-inl.h.

References folly::exception_wrapper_detail::fold(), and value.

599  {
600  using StdEx = exception_wrapper_detail::
602  auto impl = exception_wrapper_detail::fold(
603  HandleStdExceptReduce<std::is_const<This>::value>{},
604  [&](auto&& continuation) {
605  return continuation(
606  const_cast<StdEx*>(this_.vptr_->get_exception_(&this_)));
607  },
608  fns...);
609  // This continuation gets evaluated if CatchFns... does not include a
610  // catch-all handler. It is a no-op.
611  auto continuation = [](StdEx* ex) { return ex; };
612  if (nullptr != impl(continuation)) {
613  this_.throw_exception();
614  }
615 }
static const char *const value
Definition: Conv.cpp:50
FOLLY_ALWAYS_INLINE FOLLY_ATTR_VISIBILITY_HIDDEN auto fold(Fn &&, A &&a)
bool folly::exception_wrapper::has_exception_ptr ( ) const
inlinenoexcept
Returns
true if this exception_wrapper holds a reference to an exception that was thrown (i.e., if it was constructed with a std::exception_ptr, or if to_exception_ptr() was called on a (non-const) reference to *this).

Definition at line 402 of file ExceptionWrapper-inl.h.

References folly::exception_wrapper::ExceptionPtr::ops_, and vptr_.

402  {
403  return vptr_ == &ExceptionPtr::ops_;
404 }
template<class Ex >
bool folly::exception_wrapper::is_compatible_with ( ) const
inlinenoexcept
Template Parameters
ExThe expression type to check for compatibility with.
Returns
true if and only if *this wraps an exception that would be caught with a catch(Ex const&) clause.
Note
If *this is empty, this function returns false.

Definition at line 462 of file ExceptionWrapper-inl.h.

References with_exception().

Referenced by TEST().

462  {
463  return with_exception([](Ex const&) {});
464 }
std::type_info const & folly::exception_wrapper::none ( )
inlinestaticnoexcept
Returns
the typeid of an unspecified type used by exception_wrapper::type() to denote an empty exception_wrapper.

Definition at line 436 of file ExceptionWrapper-inl.h.

Referenced by class_name(), and TEST().

436  {
437  return typeid(void);
438 }
template<class Ret , class... Args>
Ret folly::exception_wrapper::noop_ ( Args...  )
inlinestaticprivate

Definition at line 62 of file ExceptionWrapper-inl.h.

62  {
63  return Ret();
64 }
void folly::exception_wrapper::onNoExceptionError ( char const *  name)
staticprivate

Definition at line 93 of file ExceptionWrapper.cpp.

Referenced by handle(), and throw_exception().

94  {
95  std::ios_base::Init ioinit_; // ensure std::cerr is alive
96  std::cerr << "Cannot use `" << name
97  << "` with an empty folly::exception_wrapper" << std::endl;
98  std::terminate();
99 }
const char * name
Definition: http_parser.c:437
folly::exception_wrapper::operator bool ( ) const
inlineexplicitnoexcept
Returns
true if *this is holding an exception.

Definition at line 390 of file ExceptionWrapper-inl.h.

References uninit_, and vptr_.

390  {
391  return vptr_ != &uninit_;
392 }
static VTable const uninit_
bool folly::exception_wrapper::operator! ( ) const
inlinenoexcept
Returns
!bool(*this)

Definition at line 394 of file ExceptionWrapper-inl.h.

394  {
395  return !static_cast<bool>(*this);
396 }
exception_wrapper & folly::exception_wrapper::operator= ( exception_wrapper &&  that)
inlinenoexcept

Move-assigns an exception_wrapper

Precondition
this != &that
Postcondition
*this contains the value of that prior to the move
that.type() == none()

Definition at line 318 of file ExceptionWrapper-inl.h.

References folly::exception_wrapper::VTable::delete_, and vptr_.

319  {
320  vptr_->delete_(this); // Free the current exception
321  (vptr_ = that.vptr_)->move_(&that, this); // Move into *this, won't throw
322  return *this;
323 }
void(* delete_)(exception_wrapper *)
exception_wrapper & folly::exception_wrapper::operator= ( exception_wrapper const &  that)
inlinenoexcept

Copy-assigns an exception_wrapper

Postcondition
*this contains a copy of that, and that is unmodified
type() == that.type()

Definition at line 325 of file ExceptionWrapper-inl.h.

References exception_wrapper().

326  {
327  exception_wrapper(that).swap(*this);
328  return *this;
329 }
void folly::exception_wrapper::reset ( )
inline

Make this exception_wrapper empty

Postcondition
!*this

Definition at line 398 of file ExceptionWrapper-inl.h.

References folly::exception_wrapper::VTable::delete_, and vptr_.

Referenced by ~exception_wrapper().

398  {
399  vptr_->delete_(this);
400 }
void(* delete_)(exception_wrapper *)
void folly::exception_wrapper::swap ( exception_wrapper that)
inlinenoexcept

Swaps the value of *this with the value of that

Definition at line 384 of file ExceptionWrapper-inl.h.

References folly::gen::move.

384  {
385  exception_wrapper tmp(std::move(that));
386  that = std::move(*this);
387  *this = std::move(tmp);
388 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
void folly::exception_wrapper::throw_exception ( ) const
inline

Throws the wrapped expression.

Precondition
bool(*this)

Definition at line 466 of file ExceptionWrapper-inl.h.

References onNoExceptionError(), folly::exception_wrapper::VTable::throw_, and vptr_.

Referenced by TEST(), throw_with_nested(), and folly::Try< void >::throwIfFailed().

466  {
467  vptr_->throw_(this);
468  onNoExceptionError(__func__);
469 }
static void onNoExceptionError(char const *name)
void(* throw_)(exception_wrapper const *)
template<class Ex >
void folly::exception_wrapper::throw_with_nested ( Ex &&  ex) const
inline

Throws the wrapped expression nested into another exception.

Precondition
bool(*this)
Template Parameters
exException in *this will be thrown nested into ex;

Definition at line 472 of file ExceptionWrapper-inl.h.

References throw_exception().

472  {
473  try {
474  throw_exception();
475  } catch (...) {
476  std::throw_with_nested(std::forward<Ex>(ex));
477  }
478 }
std::exception_ptr const & folly::exception_wrapper::to_exception_ptr ( )
inlinenoexcept
Returns
A std::exception_ptr that references either the exception held by *this, or a copy of same.
Note
This function may need to throw an exception to complete the action.
The non-const overload of this function mutates *this to cache the computed std::exception_ptr; that is, this function may cause has_exception_ptr() to change from false to true.

Definition at line 428 of file ExceptionWrapper-inl.h.

References eptr_, folly::exception_wrapper::VTable::get_exception_ptr_, folly::exception_wrapper::ExceptionPtr::ptr_, and vptr_.

Referenced by TEST().

428  {
429  // Computing an exception_ptr is expensive so cache the result.
430  return (*this = vptr_->get_exception_ptr_(this)).eptr_.ptr_;
431 }
exception_wrapper(* get_exception_ptr_)(exception_wrapper const *)
std::exception_ptr folly::exception_wrapper::to_exception_ptr ( ) const
inlinenoexcept

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Definition at line 432 of file ExceptionWrapper-inl.h.

References eptr_, folly::exception_wrapper::VTable::get_exception_ptr_, folly::exception_wrapper::ExceptionPtr::ptr_, and vptr_.

432  {
433  return vptr_->get_exception_ptr_(this).eptr_.ptr_;
434 }
exception_wrapper(* get_exception_ptr_)(exception_wrapper const *)
std::type_info const & folly::exception_wrapper::type ( ) const
inlinenoexcept

Returns the typeid of the wrapped exception object. If there is no wrapped exception object, returns exception_wrapper::none(). If this instance wraps an exception of unknown type not derived from std::exception, returns exception_wrapper::unknown().

Definition at line 443 of file ExceptionWrapper-inl.h.

References folly::exception_wrapper::VTable::type_, and vptr_.

Referenced by class_name().

443  {
444  return *vptr_->type_(this);
445 }
std::type_info const *(* type_)(exception_wrapper const *)
std::type_info const * folly::exception_wrapper::uninit_type_ ( exception_wrapper const *  )
inlinestaticprivate

Definition at line 66 of file ExceptionWrapper-inl.h.

67  {
68  return &typeid(void);
69 }
std::type_info const & folly::exception_wrapper::unknown ( )
inlinestaticnoexcept
Returns
the typeid of an unspecified type used by exception_wrapper::type() to denote an exception_wrapper that holds an exception of unknown type.

Definition at line 439 of file ExceptionWrapper-inl.h.

Referenced by class_name().

439  {
440  return typeid(Unknown);
441 }
template<class Ex , class Fn >
bool folly::exception_wrapper::with_exception ( Fn  fn)
inline

Call fn with the wrapped exception (if any), if fn can accept it.

Example
exception_wrapper ew{std::runtime_error("goodbye cruel world")};
assert( ew.with_exception([](std::runtime_error& e){/*...*/}) );
assert( !ew.with_exception([](int& e){/*...*/}) );
assert( !exception_wrapper{}.with_exception([](int& e){/*...*/}) );
Template Parameters
ExOptionally, the type of the exception that fn accepts.
FnThe type of a monomophic function object.
Parameters
fnA function object to call with the wrapped exception
Returns
true if and only if fn was called.
Note
Optionally, you may explicitly specify the type of the exception that fn expects, as in
ew.with_exception<std::runtime_error>([](auto&& e) { /*...*/; });
The handler may or may not be invoked with an active exception. Do not try to rethrow the exception with throw; from within your handler – that is, a throw expression with no operand. This may cause your process to terminate. (It is perfectly ok to throw from a handler so long as you specify the exception to throw, as in throw e;.)

Definition at line 650 of file ExceptionWrapper-inl.h.

References folly::gen::move.

Referenced by get_exception(), is_compatible_with(), and TEST().

650  {
651  return with_exception_<Ex>(*this, std::move(fn));
652 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
template<class Ex , class Fn >
bool folly::exception_wrapper::with_exception ( Fn  fn) const
inline

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Definition at line 654 of file ExceptionWrapper-inl.h.

References folly::gen::move.

654  {
655  return with_exception_<Ex const>(*this, std::move(fn));
656 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
template<class Ex , class This , class Fn >
bool folly::exception_wrapper::with_exception_ ( This &  this_,
Fn  fn_ 
)
inlinestaticprivate

Definition at line 637 of file ExceptionWrapper-inl.h.

References folly::gen::all(), folly::exception_wrapper_detail::catch_(), handle_(), handled, and folly::gen::move.

637  {
638  if (!this_) {
639  return false;
640  }
641  bool handled = true;
643  static_cast<Ex*>(nullptr), std::move(fn_));
644  auto&& all = [&](...) { handled = false; };
645  handle_(IsStdException<arg_type<decltype(fn)>>{}, this_, fn, all);
646  return handled;
647 }
_t< arg_type_< Fn >> arg_type
volatile bool handled
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
std::is_base_of< std::exception, _t< std::decay< Ex >>> IsStdException
catch_fn< Ex, Fn > catch_(Ex *, Fn fn)
static void handle_(std::false_type, This &this_, CatchFns &...fns)
Composed all(Predicate pred=Predicate())
Definition: Base.h:786

Member Data Documentation

union { ... }
exception_wrapper::VTable const folly::exception_wrapper::uninit_
staticprivate
Initial value:
{
&noop_<void, exception_wrapper const*, exception_wrapper*>,
&noop_<void, exception_wrapper*, exception_wrapper*>,
&noop_<void, exception_wrapper*>,
&noop_<void, exception_wrapper const*>,
&noop_<std::exception const*, exception_wrapper const*>,
&noop_<exception_wrapper, exception_wrapper const*>}

Definition at line 206 of file ExceptionWrapper.h.

Referenced by folly::exception_wrapper::ExceptionPtr::delete_(), folly::exception_wrapper::InPlace< Ex >::delete_(), folly::exception_wrapper::SharedPtr::delete_(), and operator bool().


The documentation for this class was generated from the following files: