Skip to content

Error Handling

See Error Classes for the complete API reference of all error types.

Cancelled operations reject with AbortError, or with the abort signal.reason wherever the op checks cancellation (e.g. sleep rejects with the reason, so a timeout() expiry surfaces as TimeoutError). Use isAbortError() to check for plain cancellation:

import { isAbortError } from 'sysopkit';
try {
await sh('long-running-command');
} catch (err) {
if (isAbortError(err)) {
// gracefully handle cancellation
return;
}
throw err;
}

When a multi-host apply() exceeds its failure threshold, it throws ApplyError with every per-host result:

import { apply, ApplyError } from 'sysopkit';
import { start } from 'sysopkit/start';
await start(async (ctx) => {
try {
await apply('setup', hosts.getAll(), fn, { maxFailPercent: 20 });
} catch (err) {
if (err instanceof ApplyError) {
for (const result of err.results) {
if (!result.success) {
ctx.error(`${result.conn.name}: ${result.error}`);
}
}
}
throw err;
}
});

Operations wrap their underlying failure cause in OperationError:

import { apply } from 'sysopkit';
import { OperationError } from 'sysopkit';
await apply('configure', conn, async (ctx) => {
try {
await createFile({ path: '/etc/config', content: 'data' });
} catch (err) {
if (err instanceof OperationError) {
ctx.error(`Operation failed: ${err.cause}`);
}
throw err;
}
});

The sh() and bash() operations throw ShellError for non-zero exit codes outside the 64-78 usage-error range:

import { apply } from 'sysopkit';
import { ShellError } from 'sysopkit/op/sh';
await apply('install nginx', conn, async (ctx) => {
try {
await sh('apt install -y nginx');
} catch (err) {
if (err instanceof ShellError) {
ctx.error(`Exit code ${err.exitCode}: ${err.stderr}`);
}
throw err;
}
});