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:
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");
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user