13namespace threadschedule
50 [[nodiscard]]
auto what() const -> std::
string
59 catch (std::exception
const& e)
65 return "Unknown exception";
67 return "No exception";
93using ErrorCallback = std::function<void(TaskError
const&)>;
132 std::lock_guard<std::mutex> lock(mutex_);
133 callbacks_.push_back(std::move(callback));
134 return callbacks_.size() - 1;
145 std::lock_guard<std::mutex> lock(mutex_);
160 std::lock_guard<std::mutex> lock(mutex_);
163 for (
auto const& callback : callbacks_)
186 std::lock_guard<std::mutex> lock(mutex_);
195 std::lock_guard<std::mutex> lock(mutex_);
200 mutable std::mutex mutex_;
201 std::vector<ErrorCallback> callbacks_;
202 size_t error_count_{0};
223template <
typename Func>
224class ErrorHandledTask
227 ErrorHandledTask(Func&& func, std::shared_ptr<ErrorHandler> handler, std::string description =
"")
228 : func_(std::forward<Func>(func)), handler_(std::move(handler)), description_(std::move(description))
243 error.
exception = std::current_exception();
245 error.
thread_id = std::this_thread::get_id();
246 error.
timestamp = std::chrono::steady_clock::now();
248 handler_->handle_error(error);
255 std::shared_ptr<ErrorHandler> handler_;
256 std::string description_;
268template <
typename Func>
269auto make_error_handled_task(Func&& func, std::shared_ptr<ErrorHandler> handler, std::string description =
"")
294class FutureWithErrorHandler
297 explicit FutureWithErrorHandler(std::future<T> future)
298 : future_(std::move(future)), error_callback_(
nullptr), has_callback_(
false)
302 FutureWithErrorHandler(FutureWithErrorHandler
const&) =
delete;
303 auto operator=(FutureWithErrorHandler
const&) -> FutureWithErrorHandler& =
delete;
304 FutureWithErrorHandler(FutureWithErrorHandler&&) =
default;
305 auto operator=(FutureWithErrorHandler&&) -> FutureWithErrorHandler& =
default;
317 auto on_error(std::function<
void(std::exception_ptr)> callback) -> FutureWithErrorHandler&
319 error_callback_ = std::move(callback);
320 has_callback_ =
true;
337 return future_.get();
341 if (has_callback_ && error_callback_)
343 error_callback_(std::current_exception());
366 template <
typename Rep,
typename Period>
367 auto wait_for(std::chrono::duration<Rep, Period>
const& timeout_duration)
const
369 return future_.wait_for(timeout_duration);
379 template <
typename Clock,
typename Duration>
380 auto wait_until(std::chrono::time_point<Clock, Duration>
const& timeout_time)
const
382 return future_.wait_until(timeout_time);
390 [[nodiscard]]
auto valid() const ->
bool
392 return future_.valid();
396 std::future<T> future_;
397 std::function<void(std::exception_ptr)> error_callback_;
398 bool has_callback_{
false};
410class FutureWithErrorHandler<void>
413 explicit FutureWithErrorHandler(std::future<void> future) : future_(std::move(future)), error_callback_(
nullptr)
417 FutureWithErrorHandler(FutureWithErrorHandler
const&) =
delete;
418 auto operator=(FutureWithErrorHandler
const&) -> FutureWithErrorHandler& =
delete;
419 FutureWithErrorHandler(FutureWithErrorHandler&&) =
default;
420 auto operator=(FutureWithErrorHandler&&) -> FutureWithErrorHandler& =
default;
422 auto on_error(std::function<
void(std::exception_ptr)> callback) -> FutureWithErrorHandler&
424 error_callback_ = std::move(callback);
425 has_callback_ =
true;
437 if (has_callback_ && error_callback_)
439 error_callback_(std::current_exception());
450 template <
typename Rep,
typename Period>
451 auto wait_for(std::chrono::duration<Rep, Period>
const& timeout_duration)
const
453 return future_.wait_for(timeout_duration);
456 template <
typename Clock,
typename Duration>
457 auto wait_until(std::chrono::time_point<Clock, Duration>
const& timeout_time)
const
459 return future_.wait_until(timeout_time);
462 [[nodiscard]]
auto valid()
const ->
bool
464 return future_.valid();
468 std::future<void> future_;
469 std::function<void(std::exception_ptr)> error_callback_;
470 bool has_callback_{};
Callable wrapper that catches exceptions and routes them to an ErrorHandler.
Central registry and dispatcher for task-error callbacks.
void reset_error_count()
Reset the cumulative error count to zero.
void handle_error(TaskError const &error)
Dispatch an error to all registered callbacks.
void clear_callbacks()
Remove all registered error callbacks.
auto error_count() const -> size_t
Return the total number of errors handled since the last reset.
auto add_callback(ErrorCallback callback) -> size_t
Register an error callback.
auto on_error(std::function< void(std::exception_ptr)> callback) -> FutureWithErrorHandler &
Attach an error callback.
auto wait_until(std::chrono::time_point< Clock, Duration > const &timeout_time) const
Block until the result is ready or the given time point is reached.
auto get() -> T
Retrieve the result, invoking the error callback on failure.
auto valid() const -> bool
Check whether the future refers to a shared state.
auto wait_for(std::chrono::duration< Rep, Period > const &timeout_duration) const
Block until the result is ready or the timeout elapses.
void wait() const
Block until the result is ready.
Holds diagnostic information captured from a failed task.
std::string task_description
Optional human-readable label supplied when the task was submitted.
void rethrow() const
Re-throw the original exception.
std::exception_ptr exception
The captured exception. Never null when produced by the library.
auto what() const -> std::string
Extract the message string from the stored exception.
std::thread::id thread_id
Id of the thread on which the exception was thrown.
std::chrono::steady_clock::time_point timestamp
Monotonic timestamp recorded immediately after the exception was caught.