fix(agent): keep offline import resilient per item with os error detail

This commit is contained in:
zipg authored and GitHub committed 2026-09-19 00:22:18 +08:00
1 parent e0e6a696b0
commit 00c4d30453
20 files changed
+858 -153

No files matched your search

@@ -17,11 +17,12 @@ describe("offline Agent and standalone JRE import", () => {
});
it("uploads standalone JRE packages and preserves both result counts", async () => {
const fetchMock = vi.fn().mockResolvedValue(new Response(JSON.stringify({ count: 0, jreCount: 1 })));
const failures = [{ key: "21", is_jre: true, error: "Failed to extract JRE archive: Access is denied. (os error 5)" }];
const fetchMock = vi.fn().mockResolvedValue(new Response(JSON.stringify({ count: 0, jreCount: 1, failures })));
vi.stubGlobal("fetch", fetchMock);
const { importAgentsFromZip } = await import("../http");
const file = new File(["archive"], "renamed.tar.zst");
expect(await importAgentsFromZip(file, "import-2")).toEqual({ count: 0, jreCount: 1 });
expect(await importAgentsFromZip(file, "import-2")).toEqual({ count: 0, jreCount: 1, failures });
const [url, request] = fetchMock.mock.calls[0];
expect(url).toContain("/api/agents/import-offline");
expect(request.method).toBe("POST");
@@ -32,6 +33,11 @@ describe("offline Agent and standalone JRE import", () => {
it("remains compatible with web backends that only return a driver count", async () => {
vi.stubGlobal("fetch", vi.fn().mockResolvedValue(new Response(JSON.stringify({ count: 2 }))));
const { importAgentsFromZip } = await import("../http");
expect(await importAgentsFromZip(new File(["archive"], "drivers.zip"))).toEqual({ count: 2, jreCount: 0 });
// Older web backends report no per-item failures; the caller must still see an empty list.
expect(await importAgentsFromZip(new File(["archive"], "drivers.zip"))).toEqual({
count: 2,
jreCount: 0,
failures: [],
});
});
});
+2
View File
@@ -921,6 +921,8 @@ export type {
AgentOfflineExportCandidate,
AgentOfflineExportPreview,
AgentOfflineExportResult,
AgentOfflineImportFailure,
AgentOfflineImportResult,
DriverStoreUsage,
DriverStoreUsageItem,
DriverRuntimeHealth,
+1 -1
View File
@@ -879,7 +879,7 @@ export async function importAgentsFromZip(fileOrPath: string | File, operationId
});
if (!res.ok) throw await backendResponseError(res);
const result: AgentOfflineImportResult = await res.json();
return { count: result.count, jreCount: result.jreCount ?? 0 };
return { count: result.count, jreCount: result.jreCount ?? 0, failures: result.failures ?? [] };
}
export async function previewAgentOfflineExport(): Promise<AgentOfflineExportPreview> {
+11
View File
@@ -206,6 +206,17 @@ export interface AgentOfflineExportResult {
export interface AgentOfflineImportResult {
count: number;
jreCount: number;
/** Items the package could not install; the rest of the import still ran. */
failures: AgentOfflineImportFailure[];
}
export interface AgentOfflineImportFailure {
/** Managed JRE key (e.g. "21") or driver key (e.g. "oracle"). */
key: string;
/** True when the failed item is a managed JRE runtime rather than a driver. */
is_jre: boolean;
/** Failure text, including the underlying OS error when there is one. */
error: string;
}
export type JavaRuntimeMode = "managed" | "system" | "custom";