From 51c97cc407fbbc373e35f0b1d1055603f0334604 Mon Sep 17 00:00:00 2001 From: Thibault Le Ouay Date: Mon, 7 Jul 2025 13:25:03 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=A4=97=20Some=20test=20should=20fail=20?= =?UTF-8?q?=F0=9F=A4=97=20(#1281)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 🤗 * ci: apply automated fixes * 🤗 * ci: apply automated fixes * 🚀 * ci: apply automated fixes * 😭 * ci: apply automated fixes * 😭 * ci: apply automated fixes --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- apps/checker/handlers/ping.go | 2 +- apps/checker/handlers/tcp.go | 2 +- .../src/app/api/checker/test/tcp/schema.ts | 8 +++ .../play/checker/_components/checker-form.tsx | 38 +++++----- apps/web/src/app/play/checker/api/mock.ts | 72 ++++++++++++++++++- apps/web/src/app/play/checker/api/route.ts | 4 +- .../monitor/data-table-row-actions.tsx | 9 +-- .../web/src/components/forms/monitor/form.tsx | 37 +++++----- .../forms/monitor/request-test-button.tsx | 4 +- .../ping-response-analysis/columns.tsx | 10 +-- .../ping-response-analysis/utils.ts | 26 +++++-- 11 files changed, 155 insertions(+), 57 deletions(-) diff --git a/apps/checker/handlers/ping.go b/apps/checker/handlers/ping.go index 9fcc0396..1db41834 100644 --- a/apps/checker/handlers/ping.go +++ b/apps/checker/handlers/ping.go @@ -146,7 +146,7 @@ func (h Handler) PingRegionHandler(c *gin.Context) { return nil } if err := backoff.Retry(op, backoff.WithMaxRetries(backoff.NewExponentialBackOff(), 3)); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request"}) + c.JSON(http.StatusOK, gin.H{"message": "url not reachable"}) return } diff --git a/apps/checker/handlers/tcp.go b/apps/checker/handlers/tcp.go index ff6e2db4..d5ad6021 100644 --- a/apps/checker/handlers/tcp.go +++ b/apps/checker/handlers/tcp.go @@ -331,7 +331,7 @@ func (h Handler) TCPHandlerRegion(c *gin.Context) { } if err := backoff.Retry(op, backoff.WithMaxRetries(backoff.NewExponentialBackOff(), 3)); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request"}) + c.JSON(http.StatusOK, gin.H{"message": "uri not reachable"}) return } diff --git a/apps/web/src/app/api/checker/test/tcp/schema.ts b/apps/web/src/app/api/checker/test/tcp/schema.ts index 382fbb69..317551e9 100644 --- a/apps/web/src/app/api/checker/test/tcp/schema.ts +++ b/apps/web/src/app/api/checker/test/tcp/schema.ts @@ -26,4 +26,12 @@ export const TCPResponse = z.object({ latency: z.number().optional(), }); +export const TCPResponseTest = TCPResponse.extend({ + state: z.literal("success").default("success"), +}).or( + z.object({ + type: z.literal("tcp").default("tcp"), + state: z.literal("error").default("error"), + }), +); export type tcpPayload = z.infer; diff --git a/apps/web/src/app/play/checker/_components/checker-form.tsx b/apps/web/src/app/play/checker/_components/checker-form.tsx index 22a733c0..651d65c2 100644 --- a/apps/web/src/app/play/checker/_components/checker-form.tsx +++ b/apps/web/src/app/play/checker/_components/checker-form.tsx @@ -172,12 +172,14 @@ export function CheckerForm({ defaultValues, defaultData }: CheckerFormProps) { setResult(currentResult); if (_result) { - toast.loading( - `Checking ${regionFormatter(_result[0].region, "long")} (${latencyFormatter(_result[0].latency)})`, - { - id: toastId, - }, - ); + if (_result[0].state === "success") { + toast.loading( + `Checking ${regionFormatter(_result[0].region, "long")} (${latencyFormatter(_result[0].latency)})`, + { + id: toastId, + }, + ); + } } } } @@ -360,17 +362,19 @@ function TableResult({ {result.length > 0 ? ( - result.map((item) => ( - - - {regionFormatter(item.region, "long")} - - - - {latencyFormatter(item.latency)} - - - )) + result + .filter((item) => item.state === "success") + .map((item) => ( + + + {regionFormatter(item.region, "long")} + + + + {latencyFormatter(item.latency)} + + + )) ) : ( check.region === region); + const response = data.checks + .filter((i) => i.state === "success") + .find((check) => check.region === region); if (!response) { throw new Error("Region not found"); @@ -58,6 +60,8 @@ export const data = { { type: "http", status: 200, + state: "success", + latency: 1602, headers: { Age: "0", @@ -95,6 +99,8 @@ export const data = { { type: "http", status: 200, + state: "success", + latency: 823, headers: { Age: "0", @@ -131,6 +137,8 @@ export const data = { }, { type: "http", + state: "success", + status: 200, latency: 1198, headers: { @@ -168,6 +176,8 @@ export const data = { }, { type: "http", + state: "success", + status: 200, latency: 1423, headers: { @@ -205,6 +215,8 @@ export const data = { }, { type: "http", + state: "success", + status: 200, latency: 1134, headers: { @@ -242,6 +254,8 @@ export const data = { }, { type: "http", + state: "success", + status: 200, latency: 812, headers: { @@ -279,6 +293,8 @@ export const data = { }, { type: "http", + state: "success", + status: 200, latency: 1081, headers: { @@ -316,6 +332,8 @@ export const data = { }, { type: "http", + state: "success", + status: 200, latency: 1329, headers: { @@ -353,6 +371,8 @@ export const data = { }, { type: "http", + state: "success", + status: 200, latency: 380, headers: { @@ -390,6 +410,8 @@ export const data = { }, { type: "http", + state: "success", + status: 200, latency: 802, headers: { @@ -427,6 +449,8 @@ export const data = { }, { type: "http", + state: "success", + status: 200, latency: 615, headers: { @@ -463,6 +487,8 @@ export const data = { }, { type: "http", + state: "success", + status: 200, latency: 1481, headers: { @@ -500,6 +526,8 @@ export const data = { }, { type: "http", + state: "success", + status: 200, latency: 768, headers: { @@ -537,6 +565,8 @@ export const data = { }, { type: "http", + state: "success", + status: 200, latency: 662, headers: { @@ -574,6 +604,8 @@ export const data = { }, { type: "http", + state: "success", + status: 200, latency: 1543, headers: { @@ -611,6 +643,8 @@ export const data = { }, { type: "http", + state: "success", + status: 200, latency: 369, headers: { @@ -648,6 +682,8 @@ export const data = { }, { type: "http", + state: "success", + status: 200, latency: 1264, headers: { @@ -685,6 +721,8 @@ export const data = { }, { type: "http", + state: "success", + status: 200, latency: 642, headers: { @@ -722,6 +760,8 @@ export const data = { }, { type: "http", + state: "success", + status: 200, latency: 627, headers: { @@ -759,6 +799,8 @@ export const data = { }, { type: "http", + state: "success", + status: 200, latency: 951, headers: { @@ -796,6 +838,8 @@ export const data = { }, { type: "http", + state: "success", + status: 200, latency: 808, headers: { @@ -833,6 +877,8 @@ export const data = { }, { type: "http", + state: "success", + status: 200, latency: 1301, headers: { @@ -870,6 +916,8 @@ export const data = { }, { type: "http", + state: "success", + status: 200, latency: 1079, headers: { @@ -907,6 +955,8 @@ export const data = { }, { type: "http", + state: "success", + status: 200, latency: 1349, headers: { @@ -943,6 +993,8 @@ export const data = { }, { type: "http", + state: "success", + status: 200, latency: 970, headers: { @@ -980,6 +1032,8 @@ export const data = { }, { type: "http", + state: "success", + status: 200, latency: 1539, headers: { @@ -1017,6 +1071,8 @@ export const data = { }, { type: "http", + state: "success", + status: 200, latency: 1347, headers: { @@ -1054,6 +1110,8 @@ export const data = { }, { type: "http", + state: "success", + status: 200, latency: 400, headers: { @@ -1091,6 +1149,8 @@ export const data = { }, { type: "http", + state: "success", + status: 200, latency: 883, headers: { @@ -1128,6 +1188,8 @@ export const data = { }, { type: "http", + state: "success", + status: 200, latency: 825, headers: { @@ -1165,6 +1227,8 @@ export const data = { }, { type: "http", + state: "success", + status: 200, latency: 526, headers: { @@ -1202,6 +1266,8 @@ export const data = { }, { type: "http", + state: "success", + status: 200, latency: 869, headers: { @@ -1238,6 +1304,8 @@ export const data = { }, { type: "http", + state: "success", + status: 200, latency: 1133, headers: { @@ -1275,6 +1343,8 @@ export const data = { }, { type: "http", + state: "success", + status: 200, latency: 447, headers: { diff --git a/apps/web/src/app/play/checker/api/route.ts b/apps/web/src/app/play/checker/api/route.ts index 72f30519..cf1e0a9e 100644 --- a/apps/web/src/app/play/checker/api/route.ts +++ b/apps/web/src/app/play/checker/api/route.ts @@ -31,7 +31,9 @@ async function* makeIterator({ check.body = undefined; // Drop the body to avoid storing it in Redis Cache } - storeCheckerData({ check, id }); + if (check.state === "success") { + storeCheckerData({ check, id }); + } return encoder.encode( `${JSON.stringify({ diff --git a/apps/web/src/components/data-table/monitor/data-table-row-actions.tsx b/apps/web/src/components/data-table/monitor/data-table-row-actions.tsx index 609540a2..93857e3c 100644 --- a/apps/web/src/components/data-table/monitor/data-table-row-actions.tsx +++ b/apps/web/src/components/data-table/monitor/data-table-row-actions.tsx @@ -31,7 +31,7 @@ import type { RegionChecker } from "@/components/ping-response-analysis/utils"; import { toast, toastAction } from "@/lib/toast"; import { api } from "@/trpc/client"; -import type { TCPResponse } from "@/app/api/checker/test/tcp/schema"; +import type { TCPResponseTest } from "@/app/api/checker/test/tcp/schema"; import { useCopyToClipboard } from "@/hooks/use-copy-to-clipboard"; interface DataTableRowActionsProps { @@ -79,13 +79,14 @@ export function DataTableRowActions({ }); const data = (await res.json()) as | RegionChecker - | z.infer; + | z.infer; // FIXME: assertions + // it's getting 😭 const success = - data.type === "http" + data.state === "success" && data.type === "http" ? data.status >= 200 && data.status < 300 - : !data.error; + : data.state === "success" && data.type === "tcp" && !data.error; if (success) { toastAction("test-success"); diff --git a/apps/web/src/components/forms/monitor/form.tsx b/apps/web/src/components/forms/monitor/form.tsx index 0cfba4bb..1cbe5013 100644 --- a/apps/web/src/components/forms/monitor/form.tsx +++ b/apps/web/src/components/forms/monitor/form.tsx @@ -229,26 +229,29 @@ export function MonitorForm({ const _headers: Record = {}; // biome-ignore lint/suspicious/noAssignInExpressions: res.headers.forEach((value, key) => (_headers[key] = value)); - - if (as.length > 0) { - for (const a of as) { - const { success, message } = a.assert({ - body: data.body ?? "", - header: data.headers ?? {}, - status: data.status, - }); - if (!success) { - return { data, error: `Assertion error: ${message}` }; + if (data.state === "success") { + if (as.length > 0) { + for (const a of as) { + const { success, message } = a.assert({ + body: data.body ?? "", + header: data.headers ?? {}, + status: data.status, + }); + if (!success) { + return { data, error: `Assertion error: ${message}` }; + } + } + } else { + // default assertion if no assertions are provided + if (res.status < 200 || res.status >= 300) { + return { + data, + error: `Assertion error: The response status was not 2XX: ${data.status}.`, + }; } } } else { - // default assertion if no assertions are provided - if (res.status < 200 || res.status >= 300) { - return { - data, - error: `Assertion error: The response status was not 2XX: ${data.status}.`, - }; - } + return { data, error: `Request error: ${data}` }; } return { data, error: undefined }; diff --git a/apps/web/src/components/forms/monitor/request-test-button.tsx b/apps/web/src/components/forms/monitor/request-test-button.tsx index c3acc12b..7e969c4b 100644 --- a/apps/web/src/components/forms/monitor/request-test-button.tsx +++ b/apps/web/src/components/forms/monitor/request-test-button.tsx @@ -135,10 +135,10 @@ export function RequestTestButton({ form, pingEndpoint, limits }: Props) { Response - {check ? ( + {check?.data.state === "success" ? (
- {check.data.type === "http" ? ( + {check.data.state === "success" && check.data.type === "http" ? ( ; export type Checker = z.infer; // FIXME: does not include TCP! export type RegionChecker = z.infer; +export type RegionCheckerResponse = z.infer; export type Method = | "GET" | "HEAD" @@ -136,6 +149,7 @@ export type Method = | "TRACE"; export type CachedRegionChecker = z.infer; +export type ErrorRequest = z.infer; export async function checkRegion( url: string, region: MonitorFlyRegion, @@ -144,7 +158,7 @@ export async function checkRegion( headers?: { value: string; key: string }[]; body?: string; }, -): Promise { +): Promise { // const res = await fetch(`https://checker.openstatus.dev/ping/${region}`, { headers: { @@ -172,10 +186,10 @@ export async function checkRegion( const json = await res.json(); - const data = checkerSchema.safeParse(json); + const data = checkerSchema.or(errorRequest).safeParse(json); if (!data.success) { - console.error(res); + console.error(JSON.stringify(res)); console.error(JSON.stringify(json)); console.error( `something went wrong with request to ${url} error ${data.error.message}`, @@ -197,8 +211,10 @@ export async function checkAllRegions(url: string, opts?: { method: Method }) { return await Promise.all( flyRegions.map(async (region) => { const check = await checkRegion(url, region, opts); - // REMINDER: dropping the body to avoid storing it within Redis Cache (Err max request size exceeded) - check.body = undefined; + if (check.state === "success") { + // REMINDER: dropping the body to avoid storing it within Redis Cache (Err max request size exceeded) + check.body = undefined; + } return check; }), ); -- 2.51.2