fix(deploy): normalize Docker access errors and harden SSE parsing

- handle malformed plain-text SSE payloads safely
- normalize Docker socket permission errors
- verify authoritative deployment job status
- preserve deployment logs on failure
This commit is contained in:
KodekaTeam committed 2026-07-19 12:54:52 +07:00
1 parent 323596c586
commit 73b4b6255d
8 files changed
+182 -31

No files matched your search

@@ -789,6 +789,7 @@ export default function DeployContainerModal({
let processLogLines = [
`[deploy] Starting deployment for ${form.name || "new container"}`,
];
let latestTerminalLogs = [...processLogLines];
try {
if (!choice) {
@@ -800,7 +801,7 @@ export default function DeployContainerModal({
`[deploy] Source: ${choice}`,
`[deploy] Server ID: ${form.serverId}`,
];
let latestTerminalLogs = [...processLogLines];
latestTerminalLogs = [...processLogLines];
const updateProcessTerminal = (
lines: string[],
@@ -1010,6 +1011,12 @@ export default function DeployContainerModal({
},
});
// The status event can race with stream closure or be altered by a
// reverse proxy. The job endpoint is the authoritative final result.
const settledJob = await containersApi.getJob(job.id);
finalStatus = settledJob.data.status;
finalError = settledJob.data.error ?? settledJob.data.cancelReason;
if (cancelRequestedRef.current && finalStatus !== "cancelled") {
const cancelledJob = currentJobIdRef.current
? await containersApi.getJob(currentJobIdRef.current)
@@ -1029,6 +1036,12 @@ export default function DeployContainerModal({
throw new Error(finalError || "Deployment cancelled");
}
if (finalStatus !== "success") {
throw new Error(
"The deployment log stream ended before the server reported a final result. Check the job status and retry the deployment.",
);
}
updateDeployTimelineModal({
onProcessUpdate,
activeStep: 3,
@@ -1067,6 +1080,7 @@ export default function DeployContainerModal({
onProcessUpdate,
name: form.name,
message,
terminalLogs: latestTerminalLogs,
});
onProcessUpdate?.({ cancelAction: undefined });
} finally {
@@ -120,14 +120,17 @@ export function failDeployTimelineModal({
onProcessUpdate,
name,
message,
terminalLogs,
}: {
onProcessUpdate?: ProcessLogUpdateHandler;
name: string;
message: string;
terminalLogs?: string[];
}) {
onProcessUpdate?.({
timelineLogs: createFailedDeployTimeline(2),
terminalLogs: [
...(terminalLogs ?? []),
`[deploy] Deployment failed for ${name || "new container"}`,
`[error] ${message}`,
],