From 7acf21a7bcac86ddd370aa2fa4941bb0f9e8df89 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Fri, 26 Jan 2018 10:53:14 -0800 Subject: [PATCH] src: handle exceptions in env->SetImmediates Backport-PR-URL: https://github.com/nodejs/node/pull/19185 PR-URL: https://github.com/nodejs/node/pull/18297 Reviewed-By: Anna Henningsen Reviewed-By: Matteo Collina --- src/env.cc | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/env.cc b/src/env.cc index ca023125c2627c..50038b73160db7 100644 --- a/src/env.cc +++ b/src/env.cc @@ -296,13 +296,26 @@ void Environment::RunAndClearNativeImmediates() { size_t ref_count = 0; std::vector list; native_immediate_callbacks_.swap(list); - for (const auto& cb : list) { - cb.cb_(this, cb.data_); - if (cb.keep_alive_) - cb.keep_alive_->Reset(); - if (cb.refed_) - ref_count++; - } + auto drain_list = [&]() { + v8::TryCatch try_catch(isolate()); + for (auto it = list.begin(); it != list.end(); ++it) { + it->cb_(this, it->data_); + if (it->keep_alive_) + it->keep_alive_->Reset(); + if (it->refed_) + ref_count++; + if (UNLIKELY(try_catch.HasCaught())) { + FatalException(isolate(), try_catch); + // Bail out, remove the already executed callbacks from list + // and set up a new TryCatch for the other pending callbacks. + std::move_backward(it, list.end(), list.begin() + (list.end() - it)); + list.resize(list.end() - it); + return true; + } + } + return false; + }; + while (drain_list()) {} #ifdef DEBUG CHECK_GE(immediate_info()->count(), count);