Stderr and Error Handling
Standard input and standard output from a process are handled directly as iterable data. There is a third data stream, standard error, that is a bit of an outlier. Standard error is meant to be used either purely for error text from the process or for some combination of logging and errors.
We are going to discuss how to handle standard error and how this relates to
error handling in the proc
library. There are examples if you want to skip
ahead.
Default behavior of stderr
and errors:
- all process
stderr
will be written toDeno.stderr
- any exit code other than 0 will throw an
ExitCodeError
- if the process ends due to a signal, it will throw a
SignalError
- an error coming from upstream (
stdin
) will be wrapped in anUpstreamError
While the default behaviors are usually adequate, these can be overridden. There is no standard for standard error, so it may take some effort to get the results you want.
Taking Control of Stderr
You can capture stderr by defining fnStderr
in the process options. This
example adds a timestamp and colors the stderr text red.
const decoratedStderr: ProcessOptions<void> = {
fnStderr: async (stderr) => {
for await (const line of stderr.lines) {
console.error(`${gray(new Date().toISOString())} ${red(line)}`);
}
},
};
await run(
{ ...decoratedStderr },
"bash",
"-c",
`
echo "This goes to stderr." >&2
echo "This goes to stdout."
`,
).toStdout();
Reinterpreting Process Errors
Catch and reinterpret exit code error, no stderr scraping.
Throwing Errors based on Stderr
Scrape stderr to throw an error. Simple version. Mention the "contract" with process that all lines of stdout should be printed, or logged, or something - where ever you put it, make sure nothing gets dropped. So error goes at the end, once all lines have been processed.
Throwing Errors based on Stderr (Advanced)
Scrape stderr to throw an error. Full version.