fix: trace turn status read disconnects

This commit is contained in:
lyon
2026-06-22 01:23:48 +08:00
parent 2d8e437a2b
commit 13d74c3c06
+53 -12
View File
@@ -1987,19 +1987,60 @@ export async function handleCodeAgentTurnHttp(request, response, url, options) {
return;
}
const requestOptions = codeAgentRequestScopedOptions(options);
const projectMismatch = await measureCodeAgentHttpPhase(requestOptions, "turn_project_check", () => traceProjectMismatchSnapshot(traceId, url, requestOptions, "turn"));
if (projectMismatch) {
recordCodeAgentTurnReadMetric(options, url, projectMismatch.statusCode, projectMismatch.body, startedAt);
sendJson(response, projectMismatch.statusCode, projectMismatch.body);
return;
}
const resolved = await measureCodeAgentHttpPhase(requestOptions, "turn_resolve_status", () => resolveCodeAgentTurnStatusSnapshot(traceId, requestOptions));
recordCodeAgentTurnReadMetric(options, url, resolved.statusCode, resolved.body, startedAt);
void emitCodeAgentOtelSpan("turn_status_read", traceId, requestOptions.env ?? process.env, {
startTimeMs: startedAt,
attributes: { "http.method": "GET", "http.route": "/v1/agent/turns/:traceId", "http.status_code": resolved.statusCode, status: resolved.body?.status ?? null, terminal: resolved.body?.terminal ?? null }
let completed = false;
const emitTurnStatusReadSpan = (name, attributes = {}, error = null) => {
void emitCodeAgentOtelSpan(name, traceId, requestOptions.env ?? process.env, {
startTimeMs: startedAt,
status: error ? "error" : undefined,
error,
attributes: {
"http.method": "GET",
"http.route": "/v1/agent/turns/:traceId",
durationMs: nowMs() - startedAt,
...attributes
}
});
};
response.once?.("close", () => {
if (completed) return;
emitTurnStatusReadSpan("turn_status_read.client_closed", {
status: "client_closed",
phase: "response_close",
terminal: false
}, new Error("Code Agent turn status client connection closed before response completed."));
});
sendJson(response, resolved.statusCode, resolved.body);
try {
const projectMismatch = await measureCodeAgentHttpPhase(requestOptions, "turn_project_check", () => traceProjectMismatchSnapshot(traceId, url, requestOptions, "turn"));
if (projectMismatch) {
completed = true;
recordCodeAgentTurnReadMetric(options, url, projectMismatch.statusCode, projectMismatch.body, startedAt);
emitTurnStatusReadSpan("turn_status_read", { "http.status_code": projectMismatch.statusCode, status: projectMismatch.body?.status ?? null, terminal: projectMismatch.body?.terminal ?? null, phase: "project_check" });
sendJson(response, projectMismatch.statusCode, projectMismatch.body);
return;
}
const resolved = await measureCodeAgentHttpPhase(requestOptions, "turn_resolve_status", () => resolveCodeAgentTurnStatusSnapshot(traceId, requestOptions));
completed = true;
recordCodeAgentTurnReadMetric(options, url, resolved.statusCode, resolved.body, startedAt);
emitTurnStatusReadSpan("turn_status_read", { "http.status_code": resolved.statusCode, status: resolved.body?.status ?? null, terminal: resolved.body?.terminal ?? null, phase: "resolved" });
sendJson(response, resolved.statusCode, resolved.body);
} catch (error) {
completed = true;
const body = {
ok: false,
status: "unknown",
running: false,
terminal: false,
traceId,
error: {
code: error?.code ?? "turn_status_read_failed",
message: error?.message ?? "Code Agent turn status read failed."
},
valuesRedacted: true
};
recordCodeAgentTurnReadMetric(options, url, 500, body, startedAt);
emitTurnStatusReadSpan("turn_status_read", { "http.status_code": 500, status: body.status, terminal: false, phase: "failed", errorCode: body.error.code }, error);
sendJson(response, 500, body);
}
}
async function resolveCodeAgentTurnStatusSnapshot(traceId, options) {