mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-23 19:08:22 -06:00
fix(sandbox): surface list probe failures instead of empty results (#124881)
sandboxListCommand and fetchAndFilterContainers swallowed backend and
registry probe failures with catch(() => []). A broken Docker daemon or
corrupt registry rendered as 'No sandbox runtimes found.' — and in
recreate, filtered an entire fleet down to nothing — indistinguishable
from a clean empty state. --json emitted a success envelope for a
failed probe.
Root cause: failure collapsed into the empty success shape at the
consumer. The listers now propagate; the sandbox CLI runner already
owns the error path (message + exit 1), and the new --json failure
contract (6c66f48a7c) emits the JSON error envelope.
Regression: replaced the test that enshrined the masking ('handle
errors gracefully' asserting the empty-state message) with the
propagation contract — fails pre-fix.
This commit is contained in:
committed by
GitHub
parent
b8a95e082b
commit
5dc4cf602b
@@ -169,12 +169,15 @@ describe("sandboxListCommand", () => {
|
||||
});
|
||||
|
||||
describe("error handling", () => {
|
||||
it("should handle errors gracefully", async () => {
|
||||
it("propagates backend probe failures instead of rendering an empty list", async () => {
|
||||
mocks.listSandboxContainers.mockRejectedValue(new Error("Docker not available"));
|
||||
|
||||
await sandboxListCommand({ browser: false, json: false }, runtime as never);
|
||||
|
||||
expect(runtime.log).toHaveBeenCalledWith("No sandbox runtimes found.");
|
||||
// A failing probe must reach the CLI error path (message + exit 1),
|
||||
// not masquerade as "No sandbox runtimes found."
|
||||
await expect(
|
||||
sandboxListCommand({ browser: false, json: false }, runtime as never),
|
||||
).rejects.toThrow("Docker not available");
|
||||
expect(runtime.log).not.toHaveBeenCalledWith("No sandbox runtimes found.");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -51,8 +51,10 @@ export async function sandboxListCommand(
|
||||
opts: SandboxListOptions,
|
||||
runtime: RuntimeEnv,
|
||||
): Promise<void> {
|
||||
const containers = opts.browser ? [] : await listSandboxContainers().catch(() => []);
|
||||
const browsers = opts.browser ? await listSandboxBrowsers().catch(() => []) : [];
|
||||
// A failing backend/registry probe must surface, not render as an empty
|
||||
// list that reads as "no sandboxes".
|
||||
const containers = opts.browser ? [] : await listSandboxContainers();
|
||||
const browsers = opts.browser ? await listSandboxBrowsers() : [];
|
||||
|
||||
if (opts.json) {
|
||||
writeRuntimeJson(runtime, { containers, browsers });
|
||||
@@ -121,8 +123,8 @@ function validateRecreateOptions(opts: SandboxRecreateOptions, runtime: RuntimeE
|
||||
}
|
||||
|
||||
async function fetchAndFilterContainers(opts: SandboxRecreateOptions): Promise<FilteredContainers> {
|
||||
const allContainers = await listSandboxContainers().catch(() => []);
|
||||
const allBrowsers = await listSandboxBrowsers().catch(() => []);
|
||||
const allContainers = await listSandboxContainers();
|
||||
const allBrowsers = await listSandboxBrowsers();
|
||||
|
||||
let containers = opts.browser ? [] : allContainers;
|
||||
let browsers = opts.browser ? allBrowsers : [];
|
||||
|
||||
Reference in New Issue
Block a user