@@ -138,7 +138,16 @@ class WorkerThreadData {
138138 public:
139139 explicit WorkerThreadData (Worker* w)
140140 : w_(w) {
141- CHECK_EQ (uv_loop_init (&loop_), 0 );
141+ int ret = uv_loop_init (&loop_);
142+ if (ret != 0 ) {
143+ char err_buf[128 ];
144+ uv_err_name_r (ret, err_buf, sizeof (err_buf));
145+ w->custom_error_ = " ERR_WORKER_INIT_FAILED" ;
146+ w->custom_error_str_ = err_buf;
147+ w->loop_init_failed_ = true ;
148+ w->stopped_ = true ;
149+ return ;
150+ }
142151
143152 Isolate::CreateParams params;
144153 SetIsolateCreateParamsForNode (¶ms);
@@ -149,6 +158,8 @@ class WorkerThreadData {
149158 Isolate* isolate = Isolate::Allocate ();
150159 if (isolate == nullptr ) {
151160 w->custom_error_ = " ERR_WORKER_OUT_OF_MEMORY" ;
161+ w->custom_error_str_ = " Failed to create new Isolate" ;
162+ w->stopped_ = true ;
152163 return ;
153164 }
154165
@@ -206,11 +217,14 @@ class WorkerThreadData {
206217 isolate->Dispose ();
207218
208219 // Wait until the platform has cleaned up all relevant resources.
209- while (!platform_finished)
220+ while (!platform_finished) {
221+ CHECK (!w_->loop_init_failed_ );
210222 uv_run (&loop_, UV_RUN_ONCE);
223+ }
224+ }
225+ if (!w_->loop_init_failed_ ) {
226+ CheckedUvLoopClose (&loop_);
211227 }
212-
213- CheckedUvLoopClose (&loop_);
214228 }
215229
216230 private:
@@ -225,6 +239,7 @@ size_t Worker::NearHeapLimit(void* data, size_t current_heap_limit,
225239 size_t initial_heap_limit) {
226240 Worker* worker = static_cast <Worker*>(data);
227241 worker->custom_error_ = " ERR_WORKER_OUT_OF_MEMORY" ;
242+ worker->custom_error_str_ = " JS heap out of memory" ;
228243 worker->Exit (1 );
229244 // Give the current GC some extra leeway to let it finish rather than
230245 // crash hard. We are not going to perform further allocations anyway.
@@ -244,6 +259,7 @@ void Worker::Run() {
244259
245260 WorkerThreadData data (this );
246261 if (isolate_ == nullptr ) return ;
262+ CHECK (!data.w_ ->loop_init_failed_ );
247263
248264 Debug (this , " Starting worker with id %llu" , thread_id_);
249265 {
@@ -289,9 +305,8 @@ void Worker::Run() {
289305 TryCatch try_catch (isolate_);
290306 context = NewContext (isolate_);
291307 if (context.IsEmpty ()) {
292- // TODO(addaleax): Inform the target about the actual underlying
293- // failure.
294308 custom_error_ = " ERR_WORKER_OUT_OF_MEMORY" ;
309+ custom_error_str_ = " Failed to create new Context" ;
295310 return ;
296311 }
297312 }
@@ -421,10 +436,14 @@ void Worker::JoinThread() {
421436 Undefined (env ()->isolate ())).Check ();
422437
423438 Local<Value> args[] = {
424- Integer::New (env ()->isolate (), exit_code_),
425- custom_error_ != nullptr ?
426- OneByteString (env ()->isolate (), custom_error_).As <Value>() :
427- Null (env ()->isolate ()).As <Value>(),
439+ Integer::New (env ()->isolate (), exit_code_),
440+ custom_error_ != nullptr
441+ ? OneByteString (env ()->isolate (), custom_error_).As <Value>()
442+ : Null (env ()->isolate ()).As <Value>(),
443+ !custom_error_str_.empty ()
444+ ? OneByteString (env ()->isolate (), custom_error_str_.c_str ())
445+ .As <Value>()
446+ : Null (env ()->isolate ()).As <Value>(),
428447 };
429448
430449 MakeCallback (env ()->onexit_string (), arraysize (args), args);
0 commit comments