mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-08-28 05:27:41 +00:00
fix(web): handle 404 and 501 gracefully in API loaders
Demo mode returns 404 for unimplemented endpoints instead of 501. Rename isNotImplemented to isNotAvailable covering both status codes, and use apiJsonOrNull in workflow-runs loader. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
549d85aaa7
commit
cfd0005319
3 changed files with 14 additions and 13 deletions
|
|
@ -1,21 +1,21 @@
|
|||
import { afterEach, describe, expect, mock, test } from "bun:test";
|
||||
import { getAuthConfig, isNotImplemented, loginDevToken } from "./api";
|
||||
import { getAuthConfig, isNotAvailable, loginDevToken } from "./api";
|
||||
|
||||
afterEach(() => {
|
||||
mock.restore();
|
||||
});
|
||||
|
||||
describe("isNotImplemented", () => {
|
||||
describe("isNotAvailable", () => {
|
||||
test("returns true for 501 status", () => {
|
||||
expect(isNotImplemented(501)).toBe(true);
|
||||
expect(isNotAvailable(501)).toBe(true);
|
||||
});
|
||||
|
||||
test("returns true for 404 status", () => {
|
||||
expect(isNotAvailable(404)).toBe(true);
|
||||
});
|
||||
|
||||
test("returns false for 200 status", () => {
|
||||
expect(isNotImplemented(200)).toBe(false);
|
||||
});
|
||||
|
||||
test("returns false for 404 status", () => {
|
||||
expect(isNotImplemented(404)).toBe(false);
|
||||
expect(isNotAvailable(200)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ export async function apiJson<T>(path: string, options?: ApiOptions): Promise<T>
|
|||
return response.json() as Promise<T>;
|
||||
}
|
||||
|
||||
export function isNotImplemented(status: number): boolean {
|
||||
return status === 501;
|
||||
export function isNotAvailable(status: number): boolean {
|
||||
return status === 404 || status === 501;
|
||||
}
|
||||
|
||||
export async function apiJsonOrNull<T>(
|
||||
|
|
@ -36,7 +36,7 @@ export async function apiJsonOrNull<T>(
|
|||
options?: ApiOptions,
|
||||
): Promise<T | null> {
|
||||
const response = await apiFetch(path, options);
|
||||
if (isNotImplemented(response.status)) {
|
||||
if (isNotAvailable(response.status)) {
|
||||
return null;
|
||||
}
|
||||
if (!response.ok) {
|
||||
|
|
|
|||
|
|
@ -3,11 +3,12 @@ import { ChevronDownIcon, MagnifyingGlassIcon } from "@heroicons/react/24/outlin
|
|||
import { Link, useParams } from "react-router";
|
||||
import { ciConfig, columnNames, deriveCiStatus, mapRunListItem, statusColors } from "../data/runs";
|
||||
import type { ColumnStatus, RunWithStatus } from "../data/runs";
|
||||
import { apiJson } from "../api";
|
||||
import { apiJsonOrNull } from "../api";
|
||||
import type { PaginatedRunList } from "@qltysh/fabro-api-client";
|
||||
|
||||
export async function loader({ request, params }: any) {
|
||||
const { data: apiRuns } = await apiJson<PaginatedRunList>(`/workflows/${params.name}/runs`, { request });
|
||||
const result = await apiJsonOrNull<PaginatedRunList>(`/workflows/${params.name}/runs`, { request });
|
||||
const apiRuns = result?.data ?? [];
|
||||
const runs: RunWithStatus[] = apiRuns.map((r) => ({
|
||||
...mapRunListItem(r),
|
||||
status: r.status as ColumnStatus,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue