mirror of
https://github.com/Naios/continuable.git
synced 2025-12-06 16:56:44 +08:00
Catch exceptions thrown by the continuation handler
* Forward it to the next error handler
This commit is contained in:
parent
ddd5b0a0a6
commit
4afeb141f1
@ -7,3 +7,5 @@ AllowShortCaseLabelsOnASingleLine: false
|
|||||||
AlwaysBreakTemplateDeclarations: true
|
AlwaysBreakTemplateDeclarations: true
|
||||||
BinPackArguments: true
|
BinPackArguments: true
|
||||||
FixNamespaceComments: true
|
FixNamespaceComments: true
|
||||||
|
MacroBlockBegin: "^CONTINUABLE_BLOCK_.*_BEGIN$"
|
||||||
|
MacroBlockEnd: "^CONTINUABLE_BLOCK_.*_END$"
|
||||||
|
|||||||
@ -151,6 +151,21 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if !defined(CONTINUABLE_WITH_CUSTOM_ERROR_TYPE) && \
|
||||||
|
!defined(CONTINUABLE_WITH_NO_EXCEPTIONS)
|
||||||
|
#define CONTINUABLE_BLOCK_TRY_BEGIN try {
|
||||||
|
#define CONTINUABLE_BLOCK_TRY_END \
|
||||||
|
} \
|
||||||
|
catch (...) { \
|
||||||
|
std::forward<decltype(next_callback)>(next_callback)( \
|
||||||
|
types::dispatch_error_tag{}, std::current_exception()); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define CONTINUABLE_BLOCK_TRY_BEGIN {
|
||||||
|
#define CONTINUABLE_BLOCK_TRY_END }
|
||||||
|
#endif
|
||||||
|
|
||||||
template <typename T, typename... Args>
|
template <typename T, typename... Args>
|
||||||
constexpr auto make_invoker(T&& invoke, hints::signature_hint_tag<Args...>) {
|
constexpr auto make_invoker(T&& invoke, hints::signature_hint_tag<Args...>) {
|
||||||
return invoker<std::decay_t<T>, hints::signature_hint_tag<Args...>>(
|
return invoker<std::decay_t<T>, hints::signature_hint_tag<Args...>>(
|
||||||
@ -167,13 +182,15 @@ invoker_of(traits::identity<continuable_base<Data, Annotation>>) {
|
|||||||
|
|
||||||
return make_invoker(
|
return make_invoker(
|
||||||
[](auto&& callback, auto&& next_callback, auto&&... args) {
|
[](auto&& callback, auto&& next_callback, auto&&... args) {
|
||||||
auto continuation_ =
|
CONTINUABLE_BLOCK_TRY_BEGIN
|
||||||
util::partial_invoke(std::forward<decltype(callback)>(callback),
|
auto continuation_ =
|
||||||
std::forward<decltype(args)>(args)...);
|
util::partial_invoke(std::forward<decltype(callback)>(callback),
|
||||||
|
std::forward<decltype(args)>(args)...);
|
||||||
|
|
||||||
attorney::invoke_continuation(
|
attorney::invoke_continuation(
|
||||||
std::move(continuation_),
|
std::move(continuation_),
|
||||||
std::forward<decltype(next_callback)>(next_callback));
|
std::forward<decltype(next_callback)>(next_callback));
|
||||||
|
CONTINUABLE_BLOCK_TRY_END
|
||||||
},
|
},
|
||||||
hint_of(traits::identity_of<Type>()));
|
hint_of(traits::identity_of<Type>()));
|
||||||
}
|
}
|
||||||
@ -183,11 +200,14 @@ template <typename T>
|
|||||||
constexpr auto invoker_of(traits::identity<T>) {
|
constexpr auto invoker_of(traits::identity<T>) {
|
||||||
return make_invoker(
|
return make_invoker(
|
||||||
[](auto&& callback, auto&& next_callback, auto&&... args) {
|
[](auto&& callback, auto&& next_callback, auto&&... args) {
|
||||||
auto result =
|
CONTINUABLE_BLOCK_TRY_BEGIN
|
||||||
util::partial_invoke(std::forward<decltype(callback)>(callback),
|
auto result =
|
||||||
std::forward<decltype(args)>(args)...);
|
util::partial_invoke(std::forward<decltype(callback)>(callback),
|
||||||
|
std::forward<decltype(args)>(args)...);
|
||||||
|
|
||||||
std::forward<decltype(next_callback)>(next_callback)(std::move(result));
|
std::forward<decltype(next_callback)>(next_callback)(
|
||||||
|
std::move(result));
|
||||||
|
CONTINUABLE_BLOCK_TRY_END
|
||||||
},
|
},
|
||||||
traits::identity_of<T>());
|
traits::identity_of<T>());
|
||||||
}
|
}
|
||||||
@ -196,10 +216,11 @@ constexpr auto invoker_of(traits::identity<T>) {
|
|||||||
inline auto invoker_of(traits::identity<void>) {
|
inline auto invoker_of(traits::identity<void>) {
|
||||||
return make_invoker(
|
return make_invoker(
|
||||||
[](auto&& callback, auto&& next_callback, auto&&... args) {
|
[](auto&& callback, auto&& next_callback, auto&&... args) {
|
||||||
util::partial_invoke(std::forward<decltype(callback)>(callback),
|
CONTINUABLE_BLOCK_TRY_BEGIN
|
||||||
std::forward<decltype(args)>(args)...);
|
util::partial_invoke(std::forward<decltype(callback)>(callback),
|
||||||
|
std::forward<decltype(args)>(args)...);
|
||||||
std::forward<decltype(next_callback)>(next_callback)();
|
std::forward<decltype(next_callback)>(next_callback)();
|
||||||
|
CONTINUABLE_BLOCK_TRY_END
|
||||||
},
|
},
|
||||||
traits::identity<>{});
|
traits::identity<>{});
|
||||||
}
|
}
|
||||||
@ -208,18 +229,20 @@ inline auto invoker_of(traits::identity<void>) {
|
|||||||
/// objects where std::get is applicable.
|
/// objects where std::get is applicable.
|
||||||
inline auto sequenced_unpack_invoker() {
|
inline auto sequenced_unpack_invoker() {
|
||||||
return [](auto&& callback, auto&& next_callback, auto&&... args) {
|
return [](auto&& callback, auto&& next_callback, auto&&... args) {
|
||||||
auto result =
|
CONTINUABLE_BLOCK_TRY_BEGIN
|
||||||
util::partial_invoke(std::forward<decltype(callback)>(callback),
|
auto result =
|
||||||
std::forward<decltype(args)>(args)...);
|
util::partial_invoke(std::forward<decltype(callback)>(callback),
|
||||||
|
std::forward<decltype(args)>(args)...);
|
||||||
|
|
||||||
traits::unpack(std::move(result), [&](auto&&... types) {
|
traits::unpack(std::move(result), [&](auto&&... types) {
|
||||||
/// TODO Add inplace resolution here
|
/// TODO Add inplace resolution here
|
||||||
|
|
||||||
std::forward<decltype(next_callback)>(next_callback)(
|
std::forward<decltype(next_callback)>(next_callback)(
|
||||||
std::forward<decltype(types)>(types)...);
|
std::forward<decltype(types)>(types)...);
|
||||||
});
|
});
|
||||||
|
CONTINUABLE_BLOCK_TRY_END
|
||||||
};
|
};
|
||||||
}
|
} // namespace decoration
|
||||||
|
|
||||||
// - std::pair<?, ?> -> next_callback(?, ?)
|
// - std::pair<?, ?> -> next_callback(?, ?)
|
||||||
template <typename First, typename Second>
|
template <typename First, typename Second>
|
||||||
@ -233,6 +256,9 @@ template <typename... Args>
|
|||||||
constexpr auto invoker_of(traits::identity<std::tuple<Args...>>) {
|
constexpr auto invoker_of(traits::identity<std::tuple<Args...>>) {
|
||||||
return make_invoker(sequenced_unpack_invoker(), traits::identity<Args...>{});
|
return make_invoker(sequenced_unpack_invoker(), traits::identity<Args...>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef CONTINUABLE_BLOCK_TRY_BEGIN
|
||||||
|
#undef CONTINUABLE_BLOCK_TRY_END
|
||||||
} // namespace decoration
|
} // namespace decoration
|
||||||
|
|
||||||
/// Invoke the callback immediately
|
/// Invoke the callback immediately
|
||||||
@ -240,18 +266,8 @@ template <typename Invoker, typename... Args>
|
|||||||
void packed_dispatch(types::this_thread_executor_tag, Invoker&& invoker,
|
void packed_dispatch(types::this_thread_executor_tag, Invoker&& invoker,
|
||||||
Args&&... args) {
|
Args&&... args) {
|
||||||
|
|
||||||
!defined(CONTINUABLE_WITH_NO_EXCEPTIONS)
|
|
||||||
// Make it possible to throw exceptions from continuations chained
|
|
||||||
// through `then` or `flow`.
|
|
||||||
try {
|
|
||||||
std::forward<Invoker>(invoker)(std::forward<Args>(args)...);
|
|
||||||
} catch (...) {
|
|
||||||
std::current_exception();
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
// Invoke the callback with the decorated invoker immediately
|
// Invoke the callback with the decorated invoker immediately
|
||||||
std::forward<Invoker>(invoker)(std::forward<Args>(args)...);
|
std::forward<Invoker>(invoker)(std::forward<Args>(args)...);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Invoke the callback through the given executor
|
/// Invoke the callback through the given executor
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user