From 65e5a6ac8848750e94e35ec65ac37d0d4a8638cd Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Mon, 19 Jan 2015 19:22:16 +0100 Subject: Async: Error continuation. --- async/src/async.h | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) (limited to 'async/src/async.h') diff --git a/async/src/async.h b/async/src/async.h index 8fee0bc..e4b06a9 100644 --- a/async/src/async.h +++ b/async/src/async.h @@ -47,6 +47,7 @@ template using EachTask = typename detail::identity&)>>::type; template using ReduceTask = typename detail::identity&)>>::type; +using ErrorHandler = std::function; namespace Private { @@ -93,6 +94,7 @@ protected: void exec(); std::function &)> mFunc; + std::function mErrorFunc; Async::Future *mPrevFuture; Async::FutureWatcher *mPrevFutureWatcher; }; @@ -101,7 +103,7 @@ template class ThenExecutor: public Executor::type, Out, In ...> { public: - ThenExecutor(ThenTask then, ExecutorBase *parent = nullptr); + ThenExecutor(ThenTask then, ErrorHandler errorHandler = ErrorHandler(), ExecutorBase *parent = nullptr); void previousFutureReady(); private: @@ -221,9 +223,9 @@ class Job : public JobBase public: template - Job then(ThenTask func) + Job then(ThenTask func, ErrorHandler errorFunc = ErrorHandler()) { - return Job(new Private::ThenExecutor(func, mExecutor)); + return Job(new Private::ThenExecutor(func, errorFunc, mExecutor)); } template @@ -309,10 +311,11 @@ void Executor::exec() } template -ThenExecutor::ThenExecutor(ThenTask then, ExecutorBase* parent) +ThenExecutor::ThenExecutor(ThenTask then, ErrorHandler error, ExecutorBase* parent) : Executor::type, Out, In ...>(parent) { this->mFunc = then; + this->mErrorFunc = error; } template @@ -321,8 +324,19 @@ void ThenExecutor::previousFutureReady() if (this->mPrevFuture) { assert(this->mPrevFuture->isFinished()); } - this->mFunc(this->mPrevFuture ? this->mPrevFuture->value() : In() ..., - *static_cast*>(this->mResult)); + if (this->mPrevFuture && this->mPrevFuture->errorCode()) { + if (this->mErrorFunc) { + this->mErrorFunc(this->mPrevFuture->errorCode(), this->mPrevFuture->errorMessage()); + } else { + static_cast*>(this->mResult)->setError(this->mPrevFuture->errorCode(), this->mPrevFuture->errorMessage()); + //propagate error if no error handler is available + this->mFunc(this->mPrevFuture ? this->mPrevFuture->value() : In() ..., + *static_cast*>(this->mResult)); + } + } else { + this->mFunc(this->mPrevFuture ? this->mPrevFuture->value() : In() ..., + *static_cast*>(this->mResult)); + } } template -- cgit v1.2.3