Skip to content

Commit d5f4ab4

Browse files
committed
fixup! bootstrap: handle snapshot errors gracefully
1 parent e9765f3 commit d5f4ab4

File tree

2 files changed

+15
-9
lines changed

2 files changed

+15
-9
lines changed

doc/api/process.md

+3
Original file line numberDiff line numberDiff line change
@@ -3822,6 +3822,9 @@ cases:
38223822
options were set, but the port number chosen was invalid or unavailable.
38233823
* `13` **Unfinished Top-Level Await**: `await` was used outside of a function
38243824
in the top-level code, but the passed `Promise` never resolved.
3825+
* `14` **Snapshot Failure**: Node.js was started to build a V8 startup
3826+
snapshot and it failed because certain requirements of the state of
3827+
the application were not met.
38253828
* `>128` **Signal Exits**: If Node.js receives a fatal signal such as
38263829
`SIGKILL` or `SIGHUP`, then its exit code will be `128` plus the
38273830
value of the signal code. This is a standard POSIX practice, since

src/node_snapshotable.cc

+12-9
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,10 @@ void SnapshotBuilder::InitializeIsolateParams(const SnapshotData* data,
177177
const_cast<v8::StartupData*>(&(data->v8_snapshot_blob_data));
178178
}
179179

180-
constexpr int INTERNAL_ERROR = 12;
180+
// TODO(joyeecheung): share these exit code constants across the code base.
181+
constexpr int UNCAUGHT_EXCEPTION_ERROR = 1;
182+
constexpr int BOOTSTRAP_ERROR = 10;
183+
constexpr int SNAPSHOT_ERROR = 14;
181184

182185
int SnapshotBuilder::Generate(SnapshotData* out,
183186
const std::vector<std::string> args,
@@ -237,12 +240,12 @@ int SnapshotBuilder::Generate(SnapshotData* out,
237240
// without breaking compatibility.
238241
Local<Context> base_context = NewContext(isolate);
239242
if (base_context.IsEmpty()) {
240-
return INTERNAL_ERROR;
243+
return BOOTSTRAP_ERROR;
241244
}
242245

243246
Local<Context> main_context = NewContext(isolate);
244247
if (main_context.IsEmpty()) {
245-
return INTERNAL_ERROR;
248+
return BOOTSTRAP_ERROR;
246249
}
247250
// Initialize the main instance context.
248251
{
@@ -259,7 +262,7 @@ int SnapshotBuilder::Generate(SnapshotData* out,
259262

260263
// Run scripts in lib/internal/bootstrap/
261264
if (env->RunBootstrapping().IsEmpty()) {
262-
return INTERNAL_ERROR;
265+
return BOOTSTRAP_ERROR;
263266
}
264267
// If --build-snapshot is true, lib/internal/main/mksnapshot.js would be
265268
// loaded via LoadEnvironment() to execute process.argv[1] as the entry
@@ -272,12 +275,12 @@ int SnapshotBuilder::Generate(SnapshotData* out,
272275
env->InitializeInspector({});
273276
#endif
274277
if (LoadEnvironment(env, StartExecutionCallback{}).IsEmpty()) {
275-
return 1;
278+
return UNCAUGHT_EXCEPTION_ERROR;
276279
}
277280
// FIXME(joyeecheung): right now running the loop in the snapshot
278281
// builder seems to introduces inconsistencies in JS land that need to
279282
// be synchronized again after snapshot restoration.
280-
int exit_code = SpinEventLoop(env).FromMaybe(1);
283+
int exit_code = SpinEventLoop(env).FromMaybe(UNCAUGHT_EXCEPTION_ERROR);
281284
if (exit_code != 0) {
282285
return exit_code;
283286
}
@@ -294,7 +297,7 @@ int SnapshotBuilder::Generate(SnapshotData* out,
294297
#ifdef NODE_USE_NODE_CODE_CACHE
295298
// Regenerate all the code cache.
296299
if (!native_module::NativeModuleEnv::CompileAllModules(main_context)) {
297-
return INTERNAL_ERROR;
300+
return UNCAUGHT_EXCEPTION_ERROR;
298301
}
299302
native_module::NativeModuleEnv::CopyCodeCache(&(out->code_cache));
300303
for (const auto& item : out->code_cache) {
@@ -325,7 +328,7 @@ int SnapshotBuilder::Generate(SnapshotData* out,
325328
// We must be able to rehash the blob when we restore it or otherwise
326329
// the hash seed would be fixed by V8, introducing a vulnerability.
327330
if (!out->v8_snapshot_blob_data.CanBeRehashed()) {
328-
return INTERNAL_ERROR;
331+
return SNAPSHOT_ERROR;
329332
}
330333

331334
// We cannot resurrect the handles from the snapshot, so make sure that
@@ -338,7 +341,7 @@ int SnapshotBuilder::Generate(SnapshotData* out,
338341
PrintLibuvHandleInformation(env->event_loop(), stderr);
339342
}
340343
if (!queues_are_empty) {
341-
return INTERNAL_ERROR;
344+
return SNAPSHOT_ERROR;
342345
}
343346
return 0;
344347
}

0 commit comments

Comments
 (0)