This page summarizes common diagnostics and error‑handling patterns for plugin authors. The goal is predictable behavior in CI and a consistent experience with the shipped plugins.
Throw on subprocess failures by default. Only continue on error when the option is explicit (e.g., batch’s --ignore-errors), and document the behavior clearly.
Honor the global capture contract:
process.env.GETDOTENV_STDIO === 'pipe' or the merged options bag has capture: true, run your subprocess with stdio: 'pipe'.import { buildSpawnEnv } from '@karmaniverous/get-dotenv';
import {
readMergedOptions,
runCommand,
shouldCapture,
} from '@karmaniverous/get-dotenv/cliHost';
const bag = readMergedOptions(thisCommand);
const capture = shouldCapture(bag.capture);
const ctx = cli.getCtx();
const env = buildSpawnEnv(process.env, ctx.dotenv);
await runCommand([file, ...args], false, {
env,
stdio: capture ? 'pipe' : 'inherit',
});
Note: the current runCommand() helper re-emits buffered stdout only when stdio: 'pipe' is used. If you need to reliably print stderr in capture mode, prefer runCommandResult() and write stderr explicitly.
When your plugin launches a subprocess, you can emit a short diagnostic prelude similar to the cmd plugin’s --trace:
{ ...process.env, ...ctx.dotenv } (or a selected subset), print the origin (dotenv | parent | unset).This format is a best practice, not a requirement. Reuse when parity with the cmd plugin is desirable.
Always use buildSpawnEnv(process.env, ctx.dotenv) to compose and normalize the child environment before passing it to your subprocess. This avoids platform‑specific surprises:
import { buildSpawnEnv } from '@karmaniverous/get-dotenv';
const env = buildSpawnEnv(process.env, ctx.dotenv);
Prefer concise, single‑line status headers per run. Avoid verbose per‑line prefixes unless you introduce a dedicated --verbose or --debug.
See also: