Add withDb() helper for graceful DB error handling
Shared withDb() wrapper in @trails-cool/db catches database connection errors and throws a 503 Response instead of crashing the server. Re-throws React Router responses (redirects, data()). Applied to Planner session routes — replaces manual try/catch. Any route can use withDb(() => ...) for automatic 503 on DB failure. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
cadcf753a7
commit
8fb7771223
3 changed files with 33 additions and 21 deletions
|
|
@ -2,6 +2,7 @@ import { data } from "react-router";
|
|||
import type { Route } from "./+types/api.sessions";
|
||||
import { createSession, listSessions } from "~/lib/sessions";
|
||||
import { parseGpxAsync } from "@trails-cool/gpx";
|
||||
import { withDb } from "@trails-cool/db";
|
||||
|
||||
export async function action({ request }: Route.ActionArgs) {
|
||||
if (request.method !== "POST") {
|
||||
|
|
@ -15,7 +16,7 @@ export async function action({ request }: Route.ActionArgs) {
|
|||
gpx?: string;
|
||||
};
|
||||
|
||||
try {
|
||||
return withDb(async () => {
|
||||
const session = await createSession({ callbackUrl, callbackToken });
|
||||
|
||||
let initialWaypoints: Array<{ lat: number; lon: number; name?: string }> | undefined;
|
||||
|
|
@ -29,26 +30,15 @@ export async function action({ request }: Route.ActionArgs) {
|
|||
}
|
||||
|
||||
return data(
|
||||
{
|
||||
sessionId: session.id,
|
||||
url: `/session/${session.id}`,
|
||||
initialWaypoints,
|
||||
},
|
||||
{ sessionId: session.id, url: `/session/${session.id}`, initialWaypoints },
|
||||
{ status: 201 },
|
||||
);
|
||||
} catch (e) {
|
||||
return data(
|
||||
{ error: "Database unavailable", details: (e as Error).message },
|
||||
{ status: 503 },
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export async function loader(_args: Route.LoaderArgs) {
|
||||
try {
|
||||
return withDb(async () => {
|
||||
const sessions = await listSessions();
|
||||
return data({ sessions });
|
||||
} catch {
|
||||
return data({ sessions: [], error: "Database unavailable" });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { useParams, useSearchParams } from "react-router";
|
|||
import type { Route } from "./+types/session.$id";
|
||||
import { getSession } from "~/lib/sessions";
|
||||
import { data } from "react-router";
|
||||
import { withDb } from "@trails-cool/db";
|
||||
import { ClientOnly } from "~/components/ClientOnly";
|
||||
import { lazy, Suspense } from "react";
|
||||
|
||||
|
|
@ -14,7 +15,7 @@ export function meta(_args: Route.MetaArgs) {
|
|||
}
|
||||
|
||||
export async function loader({ params }: Route.LoaderArgs) {
|
||||
try {
|
||||
return withDb(async () => {
|
||||
const session = await getSession(params.id);
|
||||
if (!session) {
|
||||
throw data({ error: "Session not found" }, { status: 404 });
|
||||
|
|
@ -24,10 +25,7 @@ export async function loader({ params }: Route.LoaderArgs) {
|
|||
callbackUrl: session.callbackUrl ?? null,
|
||||
callbackToken: session.callbackToken ?? null,
|
||||
});
|
||||
} catch (e) {
|
||||
if (e instanceof Response) throw e; // Re-throw data() responses
|
||||
throw data({ error: "Database unavailable" }, { status: 503 });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export default function SessionPage({ loaderData }: Route.ComponentProps) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue