Expose child errors that only occur in stderr log output (#205)
Who knows why we can't capture these errors via the more conventional `child.on('error', (err) => { })` listener 🤷
### Before
```
RethrownError: Failed to render Hydrogen to string. In order to reproduce, feed in these arguments into `renderHydrogenToString(...)`:
renderHydrogenToString arguments: { ... }
at renderHydrogenToString (server/hydrogen-render/render-hydrogen-to-string.js:58:11)
--- Original Error ---
RethrownError: Child process exited with code 1
at assembleErrorAfterChildExitsWithErrors (server/child-process-runner/run-in-child-process.js:60:29)
--- Original Error ---
No child errors
```
### After
```
RethrownError: Failed to render Hydrogen to string. In order to reproduce, feed in these arguments into `renderHydrogenToString(...)`:
renderHydrogenToString arguments: { ... }
at renderHydrogenToString (server/hydrogen-render/render-hydrogen-to-string.js:58:11)
--- Original Error ---
RethrownError: Child process exited with code 1
at assembleErrorAfterChildExitsWithErrors (server/child-process-runner/run-in-child-process.js:60:29)
--- Original Error ---
No child errors but there might be something in stderr=node:internal/modules/cjs/loader:936
throw err;
^
Error: Cannot find module '../lib/rethrown-error'
Require stack:
- server/child-process-runner/child-fork-script.js
at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
at Function.Module._load (node:internal/modules/cjs/loader:778:27)
at Module.require (node:internal/modules/cjs/loader:1005:19)
at require (node:internal/modules/cjs/helpers:102:18)
at Object.<anonymous> (server/child-process-runner/child-fork-script.js:8:23)
at Module._compile (node:internal/modules/cjs/loader:1103:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1155:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12) {
code: 'MODULE_NOT_FOUND',
requireStack: [
'server//child-process-runner//child-fork-script.js'
]
}
```
This commit is contained in:
parent
0df1a79754
commit
f3318446f8
|
@ -26,7 +26,7 @@ if (!logOutputFromChildProcesses) {
|
||||||
|
|
||||||
const resolvedChildForkScriptPath = require.resolve('./child-fork-script');
|
const resolvedChildForkScriptPath = require.resolve('./child-fork-script');
|
||||||
|
|
||||||
function assembleErrorAfterChildExitsWithErrors(exitCode, childErrors) {
|
function assembleErrorAfterChildExitsWithErrors(exitCode, childErrors, childStdErr) {
|
||||||
assert(childErrors);
|
assert(childErrors);
|
||||||
|
|
||||||
let extraErrorsMessage = '';
|
let extraErrorsMessage = '';
|
||||||
|
@ -40,7 +40,9 @@ function assembleErrorAfterChildExitsWithErrors(exitCode, childErrors) {
|
||||||
|
|
||||||
let childErrorToDisplay;
|
let childErrorToDisplay;
|
||||||
if (childErrors.length === 0) {
|
if (childErrors.length === 0) {
|
||||||
childErrorToDisplay = new Error('No child errors');
|
childErrorToDisplay = new Error(
|
||||||
|
`No child errors but there might be something in stderr=${childStdErr}`
|
||||||
|
);
|
||||||
// Clear the stack trace part of the stack string out because this is just a
|
// Clear the stack trace part of the stack string out because this is just a
|
||||||
// note about the lack of errors, not an actual error and is just noisy with
|
// note about the lack of errors, not an actual error and is just noisy with
|
||||||
// that extra fluff.
|
// that extra fluff.
|
||||||
|
@ -68,6 +70,7 @@ async function runInChildProcess(modulePath, runArguments, { timeout }) {
|
||||||
try {
|
try {
|
||||||
let childErrors = [];
|
let childErrors = [];
|
||||||
let childExitCode = '(not set yet)';
|
let childExitCode = '(not set yet)';
|
||||||
|
let childStdErr = '';
|
||||||
|
|
||||||
const controller = new AbortController();
|
const controller = new AbortController();
|
||||||
const { signal } = controller;
|
const { signal } = controller;
|
||||||
|
@ -85,16 +88,18 @@ async function runInChildProcess(modulePath, runArguments, { timeout }) {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Since we have to use the `silent` option for the `stderr` stuff below, we
|
// Since we have to use the `silent` option for the `stderr` stuff below, we
|
||||||
// should also print out the `stdout` to our main console.
|
// should also print out the `stdout` to our main console if we want to see what's going on.
|
||||||
if (logOutputFromChildProcesses) {
|
|
||||||
child.stdout.on('data', function (data) {
|
child.stdout.on('data', function (data) {
|
||||||
|
if (logOutputFromChildProcesses) {
|
||||||
console.log('Child printed something to stdout:', String(data));
|
console.log('Child printed something to stdout:', String(data));
|
||||||
});
|
|
||||||
|
|
||||||
child.stderr.on('data', function (data) {
|
|
||||||
console.log('Child printed something to stderr:', String(data));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
child.stderr.on('data', function (data) {
|
||||||
|
if (logOutputFromChildProcesses) {
|
||||||
|
console.log('Child printed something to stderr:', String(data));
|
||||||
|
}
|
||||||
|
childStdErr += data;
|
||||||
|
});
|
||||||
|
|
||||||
// Pass the runArguments to the child by sending instead of via argv because
|
// Pass the runArguments to the child by sending instead of via argv because
|
||||||
// we will run into `Error: spawn E2BIG` and `Error: spawn ENAMETOOLONG`
|
// we will run into `Error: spawn E2BIG` and `Error: spawn ENAMETOOLONG`
|
||||||
|
@ -137,7 +142,8 @@ async function runInChildProcess(modulePath, runArguments, { timeout }) {
|
||||||
} else {
|
} else {
|
||||||
const childErrorSummary = assembleErrorAfterChildExitsWithErrors(
|
const childErrorSummary = assembleErrorAfterChildExitsWithErrors(
|
||||||
childExitCode,
|
childExitCode,
|
||||||
childErrors
|
childErrors,
|
||||||
|
childStdErr
|
||||||
);
|
);
|
||||||
reject(childErrorSummary);
|
reject(childErrorSummary);
|
||||||
}
|
}
|
||||||
|
@ -148,7 +154,8 @@ async function runInChildProcess(modulePath, runArguments, { timeout }) {
|
||||||
if (err.name === 'AbortError') {
|
if (err.name === 'AbortError') {
|
||||||
const childErrorSummary = assembleErrorAfterChildExitsWithErrors(
|
const childErrorSummary = assembleErrorAfterChildExitsWithErrors(
|
||||||
childExitCode,
|
childExitCode,
|
||||||
childErrors
|
childErrors,
|
||||||
|
childStdErr
|
||||||
);
|
);
|
||||||
reject(
|
reject(
|
||||||
new RethrownError(
|
new RethrownError(
|
||||||
|
@ -163,7 +170,11 @@ async function runInChildProcess(modulePath, runArguments, { timeout }) {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!returnedData) {
|
if (!returnedData) {
|
||||||
const childErrorSummary = assembleErrorAfterChildExitsWithErrors(childExitCode, childErrors);
|
const childErrorSummary = assembleErrorAfterChildExitsWithErrors(
|
||||||
|
childExitCode,
|
||||||
|
childErrors,
|
||||||
|
childStdErr
|
||||||
|
);
|
||||||
throw new RethrownError(
|
throw new RethrownError(
|
||||||
`No \`returnedData\` sent from child process while running the module (${modulePath}). Any child errors? (${childErrors.length})`,
|
`No \`returnedData\` sent from child process while running the module (${modulePath}). Any child errors? (${childErrors.length})`,
|
||||||
childErrorSummary
|
childErrorSummary
|
||||||
|
|
Loading…
Reference in New Issue