fix: mark a rejected standalone response entry as an error too
extractStatus returned none for any non-request entry, so a clientError annotation that landed on a standalone response frame — the fallback messageLogState uses when no request entry was there to fold into, e.g. a trimmed log or a reconnect boundary — rendered with no status badge at all. The clientError check now runs before the request-only lifecycle. Caught in Copilot's review of #1953. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SW1p8E2uiyyLx4RKwrwSrt
This commit is contained in:
parent
f201032137
commit
1e427c05f3
2 changed files with 42 additions and 3 deletions
|
|
@ -756,6 +756,41 @@ describe("ProtocolEntry — client-rejected response", () => {
|
|||
expect(screen.getByText(REASON)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// messageLogState falls back to the standalone response frame when no request
|
||||
// entry was there to fold into (a trimmed log, or a reconnect boundary). That
|
||||
// entry is not `direction: "request"`, so the request-only status lifecycle
|
||||
// would have rendered it without any badge at all.
|
||||
const rejectedStandaloneResponse: MessageEntry = {
|
||||
id: "rej-standalone",
|
||||
timestamp: new Date("2026-07-28T10:00:00Z"),
|
||||
direction: "response",
|
||||
origin: "server",
|
||||
message: {
|
||||
jsonrpc: "2.0",
|
||||
id: 11,
|
||||
result: { resultType: "complete", tools: [] },
|
||||
},
|
||||
clientError: REASON,
|
||||
};
|
||||
|
||||
it("renders Error on a rejected standalone response entry", () => {
|
||||
renderWithMantine(
|
||||
<ProtocolEntry {...baseProps} entry={rejectedStandaloneResponse} />,
|
||||
);
|
||||
expect(screen.getByText("Error")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("still renders no status badge on an unrejected standalone response", () => {
|
||||
const clean: MessageEntry = {
|
||||
...rejectedStandaloneResponse,
|
||||
clientError: undefined,
|
||||
};
|
||||
renderWithMantine(<ProtocolEntry {...baseProps} entry={clean} />);
|
||||
expect(screen.queryByText("Error")).not.toBeInTheDocument();
|
||||
expect(screen.queryByText("OK")).not.toBeInTheDocument();
|
||||
expect(screen.queryByText("Pending")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("shows no rejection alert on an ordinary success", () => {
|
||||
renderWithMantine(
|
||||
<ProtocolEntry {...baseProps} entry={successEntry} isListExpanded />,
|
||||
|
|
|
|||
|
|
@ -220,12 +220,16 @@ function extractResourceUri(entry: MessageEntry): string | undefined {
|
|||
function extractStatus(
|
||||
entry: MessageEntry,
|
||||
): "success" | "error" | "pending" | "none" {
|
||||
// A response the CLIENT refused is an error whichever entry carries it, so
|
||||
// this is checked BEFORE the request-only lifecycle below (#1953).
|
||||
// messageLogState annotates the request entry when the response was folded
|
||||
// into one, but falls back to the standalone response frame when there was
|
||||
// no matching request (a trimmed log, or a reconnect boundary) — and that
|
||||
// entry would otherwise fall straight through to "none" and render no badge.
|
||||
if (entry.clientError) return "error";
|
||||
if (entry.direction !== "request") return "none";
|
||||
if (!entry.response) return "pending";
|
||||
if ("error" in entry.response) return "error";
|
||||
// The server answered with a valid result the CLIENT then refused (#1953).
|
||||
// The call failed, so the entry must not read as a success.
|
||||
if (entry.clientError) return "error";
|
||||
return "success";
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue