Remix: Loader threw error
Remixのloaderまたはaction関数でエラーが発生した場合の対処法
概要
Remixのloaderまたはaction関数内でエラーが発生した場合のハンドリング方法です。
エラーメッセージ
``` ErrorBoundary caught error: Error in loader ```
原因
- データ取得の失敗: API呼び出しやDB接続エラー
- 認証エラー: セッションが無効
- バリデーションエラー: 不正なリクエストパラメータ
- 型エラー: undefinedアクセス
解決策
1. loaderでのエラーハンドリング
```typescript // app/routes/users.$id.tsx import { json, type LoaderFunctionArgs } from “@remix-run/node”;
export async function loader({ params }: LoaderFunctionArgs) { try { const user = await db.user.findUnique({ where: { id: params.id } });
if (!user) {
throw new Response("User not found", { status: 404 });
}
return json({ user });
} catch (error) { if (error instanceof Response) throw error;
console.error("Loader error:", error);
throw new Response("Internal Server Error", { status: 500 });
} } ```
2. ErrorBoundaryを実装
```typescript // app/routes/users.$id.tsx import { useRouteError, isRouteErrorResponse } from “@remix-run/react”;
export function ErrorBoundary() { const error = useRouteError();
if (isRouteErrorResponse(error)) { return ( {error.status} {error.data} ); }
return Something went wrong; } ```
3. actionでのバリデーション
```typescript import { z } from “zod”;
const schema = z.object({ email: z.string().email(), name: z.string().min(1), });
export async function action({ request }: ActionFunctionArgs) { const formData = await request.formData(); const result = schema.safeParse(Object.fromEntries(formData));
if (!result.success) { return json({ errors: result.error.flatten() }, { status: 400 }); }
// 処理を続行 } ```
4. セッション検証
```typescript export async function loader({ request }: LoaderFunctionArgs) { const session = await getSession(request.headers.get(“Cookie”));
if (!session.has(“userId”)) { throw redirect("/login"); }
return json({ user: await getUser(session.get(“userId”)) }); } ```
よくある間違い
- Responseではなく普通のErrorをthrow
- ErrorBoundaryの配置場所
- json()で返さずに直接オブジェクトを返す
関連エラー
関連エラー
React の他のエラー
この記事は役に立ちましたか?