@@ -133,7 +133,16 @@ class WorkerThreadData {
133133 public:
134134 explicit WorkerThreadData (Worker* w)
135135 : w_(w) {
136- CHECK_EQ (uv_loop_init (&loop_), 0 );
136+ int ret = uv_loop_init (&loop_);
137+ if (ret != 0 ) {
138+ char err_buf[128 ];
139+ uv_err_name_r (ret, err_buf, sizeof (err_buf));
140+ w->custom_error_ = " ERR_WORKER_INIT_FAILED" ;
141+ w->custom_error_str_ = err_buf;
142+ w->loop_init_failed_ = true ;
143+ w->stopped_ = true ;
144+ return ;
145+ }
137146
138147 std::shared_ptr<ArrayBufferAllocator> allocator =
139148 ArrayBufferAllocator::Create ();
@@ -146,6 +155,8 @@ class WorkerThreadData {
146155 Isolate* isolate = Isolate::Allocate ();
147156 if (isolate == nullptr ) {
148157 w->custom_error_ = " ERR_WORKER_OUT_OF_MEMORY" ;
158+ w->custom_error_str_ = " Failed to create new Isolate" ;
159+ w->stopped_ = true ;
149160 return ;
150161 }
151162
@@ -204,11 +215,14 @@ class WorkerThreadData {
204215 isolate->Dispose ();
205216
206217 // Wait until the platform has cleaned up all relevant resources.
207- while (!platform_finished)
218+ while (!platform_finished) {
219+ CHECK (!w_->loop_init_failed_ );
208220 uv_run (&loop_, UV_RUN_ONCE);
221+ }
222+ }
223+ if (!w_->loop_init_failed_ ) {
224+ CheckedUvLoopClose (&loop_);
209225 }
210-
211- CheckedUvLoopClose (&loop_);
212226 }
213227
214228 private:
@@ -223,6 +237,7 @@ size_t Worker::NearHeapLimit(void* data, size_t current_heap_limit,
223237 size_t initial_heap_limit) {
224238 Worker* worker = static_cast <Worker*>(data);
225239 worker->custom_error_ = " ERR_WORKER_OUT_OF_MEMORY" ;
240+ worker->custom_error_str_ = " JS heap out of memory" ;
226241 worker->Exit (1 );
227242 // Give the current GC some extra leeway to let it finish rather than
228243 // crash hard. We are not going to perform further allocations anyway.
@@ -242,6 +257,7 @@ void Worker::Run() {
242257
243258 WorkerThreadData data (this );
244259 if (isolate_ == nullptr ) return ;
260+ CHECK (!data.w_ ->loop_init_failed_ );
245261
246262 Debug (this , " Starting worker with id %llu" , thread_id_);
247263 {
@@ -287,9 +303,8 @@ void Worker::Run() {
287303 TryCatch try_catch (isolate_);
288304 context = NewContext (isolate_);
289305 if (context.IsEmpty ()) {
290- // TODO(addaleax): Inform the target about the actual underlying
291- // failure.
292306 custom_error_ = " ERR_WORKER_OUT_OF_MEMORY" ;
307+ custom_error_str_ = " Failed to create new Context" ;
293308 return ;
294309 }
295310 }
@@ -417,10 +432,14 @@ void Worker::JoinThread() {
417432 Undefined (env ()->isolate ())).Check ();
418433
419434 Local<Value> args[] = {
420- Integer::New (env ()->isolate (), exit_code_),
421- custom_error_ != nullptr ?
422- OneByteString (env ()->isolate (), custom_error_).As <Value>() :
423- Null (env ()->isolate ()).As <Value>(),
435+ Integer::New (env ()->isolate (), exit_code_),
436+ custom_error_ != nullptr
437+ ? OneByteString (env ()->isolate (), custom_error_).As <Value>()
438+ : Null (env ()->isolate ()).As <Value>(),
439+ !custom_error_str_.empty ()
440+ ? OneByteString (env ()->isolate (), custom_error_str_.c_str ())
441+ .As <Value>()
442+ : Null (env ()->isolate ()).As <Value>(),
424443 };
425444
426445 MakeCallback (env ()->onexit_string (), arraysize (args), args);
0 commit comments