fix: preserve adopted resource specs

This commit is contained in:
2026-09-07 03:54:19 +00:00 Unverified
parent f14e976bcd
commit 0067a2cdcd
6 changed files with 397 additions and 48 deletions
+99 -12
View File
@@ -64,7 +64,7 @@ import {
type Workspace,
type WorkspaceStore,
} from "./workspace-store";
import { REDACTED, redactString } from "./redact";
import { redactString } from "./redact";
const API_PREFIX = "/api/v2";
const RUNTIME_SESSION_MS = 24 * 60 * 60 * 1000;
@@ -121,6 +121,7 @@ export type UnknownFailureLog = {
code: string;
errorName: string;
message: string;
stack?: string;
kubernetesStatus?: { status?: string; reason?: string; code?: number };
};
@@ -334,8 +335,10 @@ export function createApp(
? error.body
: undefined;
if (!candidate) return;
const status = typeof candidate.status === "string" ? REDACTED : undefined;
const reason = typeof candidate.reason === "string" ? REDACTED : undefined;
const status =
typeof candidate.status === "string" ? candidate.status : undefined;
const reason =
typeof candidate.reason === "string" ? candidate.reason : undefined;
const code =
typeof candidate.code === "number" ? candidate.code : undefined;
return status || reason || code !== undefined
@@ -343,6 +346,51 @@ export function createApp(
: undefined;
}
function kubernetesError(
error: unknown,
): { status: number; detail: string } | undefined {
if (!isRecord(error) || typeof error.statusCode !== "number") return;
const status = error.statusCode;
if (!Number.isInteger(status) || status < 100 || status > 599) return;
const body = isRecord(error.body) ? error.body : undefined;
if (
!body ||
body.kind !== "Status" ||
body.apiVersion !== "v1" ||
body.status !== "Failure" ||
typeof body.reason !== "string" ||
typeof body.message !== "string" ||
!Number.isInteger(body.code) ||
body.code !== status
)
return;
return { status, detail: body.message };
}
function errorDiagnostics(error: unknown): {
errorName: string;
message: string;
stack?: string;
} {
if (error instanceof Error)
return {
errorName: error.name,
message: error.message,
...(error.stack && { stack: error.stack }),
};
if (isRecord(error))
return {
errorName: typeof error.name === "string" ? error.name : "UnknownError",
message:
typeof error.message === "string" ? error.message : "Unknown error",
...(typeof error.stack === "string" && { stack: error.stack }),
};
return {
errorName: "UnknownError",
message: typeof error === "string" ? error : "Unknown error",
};
}
function logRequestError(
request: Request,
error: unknown,
@@ -358,6 +406,9 @@ export function createApp(
},
): void {
const pathname = new URL(request.url).pathname;
const diagnostics = errorDiagnostics(error);
const unknownFailure =
event === "request.failed" && code === "INTERNAL_ERROR";
logger.error({
event,
requestId: requestIds.get(request) ?? makeRequestId(),
@@ -367,11 +418,13 @@ export function createApp(
...(operationId && { operationId }),
status: 500,
code,
errorName: error instanceof Error ? error.name : "UnknownError",
message: redactString(message),
...(kubernetesStatus(error) && {
kubernetesStatus: kubernetesStatus(error),
}),
errorName: diagnostics.errorName,
message: unknownFailure ? diagnostics.message : redactString(message),
...(unknownFailure && diagnostics.stack && { stack: diagnostics.stack }),
...(unknownFailure &&
kubernetesStatus(error) && {
kubernetesStatus: kubernetesStatus(error),
}),
});
}
@@ -1781,10 +1834,36 @@ export function createApp(
const workspace = await getWorkspace(id);
if (subpath === "adopt" && request.method === "POST") {
await requireCapability(identity, request, "kubernetes:write");
const adopted = await requireAdoption().adopt(
workspace.metadata.name,
workspace.metadata.uid,
);
let adopted: WorkspaceAdoptionResult;
try {
adopted = await requireAdoption().adopt(
workspace.metadata.name,
workspace.metadata.uid,
);
} catch (error) {
try {
await audit(
identity,
request,
"workspace.adopt",
"failure",
{
route: path,
requestId: requestIds.get(request) ?? makeRequestId(),
},
id,
);
} catch (auditError) {
logRequestError(request, auditError, {
event: "workspace.adopt.audit.failed",
code: "AUDIT_APPEND_FAILED",
message:
"Failed workspace adoption audit event could not be appended",
workspaceId: id,
});
}
throw error;
}
await audit(
identity,
request,
@@ -2202,6 +2281,14 @@ export function createApp(
function normalizeError(error: unknown): HttpError {
if (error instanceof HttpError) return error;
const kubernetes = kubernetesError(error);
if (kubernetes)
return new HttpError(
kubernetes.status,
"Kubernetes error",
"KUBERNETES_ERROR",
kubernetes.detail,
);
if (error instanceof WorkspaceNotFoundError)
return new HttpError(404, "Not found", error.code, error.message);
if (error instanceof OperationNotFoundError)