fix(observability): preserve HTTP error status

This commit is contained in:
Codex Review Integration 2026-09-03 21:51:40 -03:00
parent 207199559f
commit fa866c5ea7
2 changed files with 20 additions and 1 deletions

View file

@ -1,4 +1,5 @@
import { setHttpStatus, spanToJSON, startSpan, type Span } from "@sentry/react";
import { isHTTPError } from "ky";
const INTEGER_SEGMENT = /^\d+$/;
const UUID_SEGMENT = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
@ -101,7 +102,7 @@ export async function traceHttpOperation<T>(
return result;
} catch (error) {
if (!statusReported) {
reportStatus(500);
reportStatus(isHTTPError(error) ? error.response.status : 500);
}
throw error;
}

View file

@ -11,6 +11,7 @@ vi.mock("@sentry/react", () => ({
}));
import * as Sentry from "@sentry/react";
import { HTTPError } from "ky";
import { normalizeHttpRoute, traceHttpOperation } from "@/observability/http-transaction";
const startSpanMock = vi.mocked(Sentry.startSpan);
@ -125,6 +126,23 @@ describe("traceHttpOperation", () => {
expect(setHttpStatusMock).toHaveBeenCalledWith(capturedSpan, 204);
});
it("reports the Ky HTTPError response status instead of 500", async () => {
const httpError = new HTTPError(
new Response("Unauthorized", { status: 401 }),
new Request("https://api.example.test/x"),
{} as never,
);
await expect(
traceHttpOperation({ method: "GET", url: "/x", entryPoint: "fn" }, async () => {
throw httpError;
}),
).rejects.toThrow();
expect(setHttpStatusMock).toHaveBeenCalledTimes(1);
expect(setHttpStatusMock).toHaveBeenCalledWith(capturedSpan, 401);
});
it("reports status 500 when the callback throws", async () => {
await expect(
traceHttpOperation({ method: "GET", url: "/x", entryPoint: "fn" }, async () => {