fix: run advanced matcher on HTTP errors with custom up codes

When customUpCodes mark an HTTPError as up, parse the response body, apply advancedMatcher.validate, and set status to statusUp && matchResult.ok. Return parsed payload and extracted values to match the success path.
This commit is contained in:
harsh-aghara committed 2026-06-05 00:35:30 +05:30
1 parent 5628c202f7
commit dd16ac060a
2 files changed
+76 -4

No files matched your search

@@ -33,17 +33,65 @@ export class HttpProvider implements IStatusProvider<HttpStatusPayload> {
if (error instanceof HTTPError || error instanceof RequestError) {
const statusCode = error.response?.statusCode;
const statusUp = isStatusUp(statusCode, monitor.customUpCodes);
const responseTime = error.timings?.phases?.total ?? 0;
if (!statusUp) {
return {
monitorId: monitor.id,
teamId: monitor.teamId,
type: monitor.type,
status: false,
code: statusCode ?? NETWORK_ERROR,
message: error.message,
responseTime,
timings: error.timings,
payload: null as T,
};
}
const { jsonPath } = monitor;
const body = error.response?.body ?? "";
const contentType = error.response?.headers?.["content-type"] || "";
const isJson = contentType.includes("application/json");
if (jsonPath && !isJson) {
return {
monitorId: monitor.id,
teamId: monitor.teamId,
type: monitor.type,
status: false,
code: statusCode ?? NETWORK_ERROR,
message: "Response is not JSON",
responseTime,
timings: error.timings,
payload: body as unknown as T,
};
}
let payload: T;
if (isJson) {
try {
payload = JSON.parse(body) as T;
} catch {
payload = body as unknown as T;
}
} else {
payload = body as unknown as T;
}
const matchResult = this.advancedMatcher.validate<T>(payload, monitor);
return {
monitorId: monitor.id,
teamId: monitor.teamId,
type: monitor.type,
status: statusUp,
status: statusUp && matchResult.ok,
code: statusCode ?? NETWORK_ERROR,
message: error.message,
responseTime: error.timings?.phases?.total ?? 0,
message: matchResult.ok ? error.message : matchResult.message,
responseTime,
timings: error.timings,
payload: null as T,
payload,
extracted: matchResult.extracted,
};
}
@@ -408,5 +408,29 @@ describe("HttpProvider", () => {
expect(result.status).toBe(false);
expect(result.message).toBe("Body mismatch");
});
it("does not override matcher failure on HTTPError when status code is in customUpCodes", async () => {
const err = new HTTPError("Unauthorized");
(err as any).response = {
statusCode: 401,
body: '{"status":"down"}',
headers: { "content-type": "application/json" },
};
(err as any).timings = { phases: { total: 30 } };
mockGot.mockRejectedValue(err);
const matcher = createMockMatcher({
ok: false,
message: "Body mismatch",
extracted: "down",
});
const { provider } = createProvider(matcher);
const result = await provider.handle(makeMonitor({ customUpCodes: [401], useAdvancedMatching: true }));
expect(result.status).toBe(false);
expect(result.message).toBe("Body mismatch");
expect(result.payload).toEqual({ status: "down" });
expect(result.extracted).toBe("down");
});
});
});