13namespace threadschedule
21 std::exception_ptr exception;
22 std::string task_description;
23 std::thread::id thread_id;
24 std::chrono::steady_clock::time_point timestamp;
29 [[nodiscard]]
auto what() const -> std::
string
35 std::rethrow_exception(exception);
38 catch (std::exception
const& e)
44 return "Unknown exception";
46 return "No exception";
56 std::rethrow_exception(exception);
64using ErrorCallback = std::function<void(TaskError
const&)>;
82 std::lock_guard<std::mutex> lock(mutex_);
83 callbacks_.push_back(std::move(callback));
84 return callbacks_.size() - 1;
92 std::lock_guard<std::mutex> lock(mutex_);
102 std::lock_guard<std::mutex> lock(mutex_);
105 for (
auto const& callback : callbacks_)
123 std::lock_guard<std::mutex> lock(mutex_);
132 std::lock_guard<std::mutex> lock(mutex_);
137 mutable std::mutex mutex_;
138 std::vector<ErrorCallback> callbacks_;
139 size_t error_count_{0};
147template <
typename Func>
148class ErrorHandledTask
151 ErrorHandledTask(Func&& func, std::shared_ptr<ErrorHandler> handler, std::string description =
"")
152 : func_(std::forward<Func>(func)), handler_(std::move(handler)), description_(std::move(description))
167 error.exception = std::current_exception();
168 error.task_description = description_;
169 error.thread_id = std::this_thread::get_id();
170 error.timestamp = std::chrono::steady_clock::now();
172 handler_->handle_error(error);
179 std::shared_ptr<ErrorHandler> handler_;
180 std::string description_;
186template <
typename Func>
187auto make_error_handled_task(Func&& func, std::shared_ptr<ErrorHandler> handler, std::string description =
"")
198class FutureWithErrorHandler
201 explicit FutureWithErrorHandler(std::future<T> future)
202 : future_(std::move(future)), error_callback_(
nullptr), has_callback_(
false)
206 FutureWithErrorHandler(FutureWithErrorHandler
const&) =
delete;
207 auto operator=(FutureWithErrorHandler
const&) -> FutureWithErrorHandler& =
delete;
208 FutureWithErrorHandler(FutureWithErrorHandler&&) =
default;
209 auto operator=(FutureWithErrorHandler&&) -> FutureWithErrorHandler& =
default;
216 auto on_error(std::function<
void(std::exception_ptr)> callback) -> FutureWithErrorHandler&
218 error_callback_ = std::move(callback);
219 has_callback_ =
true;
230 return future_.get();
234 if (has_callback_ && error_callback_)
236 error_callback_(std::current_exception());
253 template <
typename Rep,
typename Period>
254 auto wait_for(std::chrono::duration<Rep, Period>
const& timeout_duration)
const
256 return future_.wait_for(timeout_duration);
262 template <
typename Clock,
typename Duration>
263 auto wait_until(std::chrono::time_point<Clock, Duration>
const& timeout_time)
const
265 return future_.wait_until(timeout_time);
271 [[nodiscard]]
auto valid() const ->
bool
273 return future_.valid();
277 std::future<T> future_;
278 std::function<void(std::exception_ptr)> error_callback_;
279 bool has_callback_{
false};
286class FutureWithErrorHandler<void>
289 explicit FutureWithErrorHandler(std::future<void> future) : future_(std::move(future)), error_callback_(
nullptr)
293 FutureWithErrorHandler(FutureWithErrorHandler
const&) =
delete;
294 auto operator=(FutureWithErrorHandler
const&) -> FutureWithErrorHandler& =
delete;
295 FutureWithErrorHandler(FutureWithErrorHandler&&) =
default;
296 auto operator=(FutureWithErrorHandler&&) -> FutureWithErrorHandler& =
default;
298 auto on_error(std::function<
void(std::exception_ptr)> callback) -> FutureWithErrorHandler&
300 error_callback_ = std::move(callback);
301 has_callback_ =
true;
313 if (has_callback_ && error_callback_)
315 error_callback_(std::current_exception());
326 template <
typename Rep,
typename Period>
327 auto wait_for(std::chrono::duration<Rep, Period>
const& timeout_duration)
const
329 return future_.wait_for(timeout_duration);
332 template <
typename Clock,
typename Duration>
333 auto wait_until(std::chrono::time_point<Clock, Duration>
const& timeout_time)
const
335 return future_.wait_until(timeout_time);
338 [[nodiscard]]
auto valid()
const ->
bool
340 return future_.valid();
344 std::future<void> future_;
345 std::function<void(std::exception_ptr)> error_callback_;
346 bool has_callback_{};
Task wrapper that provides error handling.
Global error handler for thread pool tasks.
void reset_error_count()
Reset error count.
void handle_error(TaskError const &error)
Handle an exception from a task.
void clear_callbacks()
Remove all error callbacks.
auto error_count() const -> size_t
Get total number of errors handled.
auto add_callback(ErrorCallback callback) -> size_t
Add 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
Wait until a specific time point.
auto get() -> T
Get the result, calling error callback if exception is thrown.
auto valid() const -> bool
Check if the future is valid.
auto wait_for(std::chrono::duration< Rep, Period > const &timeout_duration) const
Wait for the future with timeout.
void wait() const
Wait for the future to complete.
Information about a task exception.
void rethrow() const
Rethrow the exception.
auto what() const -> std::string
Get the exception message if it's a std::exception.