218 {
219 try {
221 _asyncDonePromise = std::make_unique<std::promise<void>>();
222 body()->invoke(self, spec, &_markAsyncPromiseDoneFn);
223
224 auto asyncDoneFuture = _asyncDonePromise->get_future();
226 if (asyncDoneFuture.wait_for(std::chrono::milliseconds(
get_timeout_ms())) ==
227 std::future_status::timeout) {
228 if (resultCallback) {
230 resultCallback->invoke(result.get());
231 return;
232 } else {
233 _Log_("Code block timed out");
234 }
235 }
236 }
237
238 asyncDoneFuture.get();
239
240 } else {
241 body()->invoke(self, spec,
nullptr);
242 }
243
244 if (!resultCallback) return;
246 resultCallback->invoke(result.get());
247 } catch (...) {
248 _exceptionHandled = false;
249
250
251 if (_asyncDonePromise) _asyncDonePromise->set_exception(std::current_exception());
252
254 if (auto* exceptionHandlers =
255 currentlyRunningSpecEnvironment->local_exception_handlers()) {
256 _currentExceptionMessage.clear();
257 _currentExceptionPtr =
258 std::make_unique<std::exception_ptr>(std::current_exception());
259 exceptionHandlers->foreach_exception_handler(&_forEachExceptionHandlerFn);
260 if (_exceptionHandled) {
261 if (resultCallback) {
263 self, group, spec, _currentExceptionMessage.c_str()
264 );
265 resultCallback->invoke(result.get());
266 } else {
267 _Log_("Code block error: {}", _currentExceptionMessage);
268 }
269 } else {
270 if (resultCallback) {
271 auto result =
273 resultCallback->invoke(result.get());
274
275 } else {
276 _Log_("Code block error: Unhandled exception");
277 }
278 }
279 } else {
280 _Log_("No exception handlers registered");
281 }
282 } else {
283 _Log_("No currently running spec environment");
284 }
285 }
286 }
std::uint32_t get_timeout_ms() const override
bool is_async() const override
static std::unique_ptr< SpecRunResult > timeout(ISpecComponent *component, ISpecGroup *group, ISpec *spec)
static std::unique_ptr< SpecRunResult > passed(ISpecComponent *component, ISpecGroup *group, ISpec *spec)
static std::unique_ptr< SpecRunResult > failed(ISpecComponent *component, ISpecGroup *group, ISpec *spec, std::string_view message="")
GlobalSpecEnvironment & global_spec_environment()