作成日: 9/29/2024, 7:03:59 AM
この記事ではremixの**fエラーハンドリング・コード**をまとめます。 エラーの投げ方、ErrorBoundaryComponentの仕様、MetaFunctionでのエラー処理の書き方等について書かれています。
以下のコードで、**r"404NotFound"**を発生させることができます。
throw new Response(null, {
status: 404,
statusText: "Not Found",
});エラーが投げられると、**rErrorBoundaryの処理**が発生します。 よく使うエラーステータスコード一覧:
複数のErrorBoundaryがある場合、処理は一度だけ発生します。以下に例を示します。
Parent.tsx //三番目
├── Child.tsx //二番目
└── Grandchild.tsx //一番優先される
root.tsx //最後
**g[例1] GrandChild.tsxでエラーが投げられた場合** Grandchild.tsx→Child.tsx→Parent.tsx→root.tsxの順にErrorBoundary関数を探し、一番初めに見つかった関数がエラー処理する。 **g[例2] Parent.tsxでエラーが投げられた場合** この場合は、Parent.tsx→root.tsxとErrorBoundaryを探し、エラー処理することとなる。 したがって、root.tsxにErrorBoundaryを置いておくことで、あらゆる場所のエラーに対応してもらえる。
子階層にErrorBoundaryを作成することで、エラー表示を一部に留めることができる。
Parent.tsx //いいね・検索機能
└── Child.tsx //ブログ記事
root.tsx //ヘッダー
**g[例]Child.tsxでエラーが起きたとき** Child.tsxの画面構成だけエラー画面に変わり、Parent.tsxとroot.tsxは通常通り表示される。 つまり、ブログ記事はありませんと表示したうえで、ヘッダーやフッダーその他機能を残すことができる。非常に便利。
//remixの公式サイトのコードを一部改変
export const ErrorBoundary: ErrorBoundaryComponent = () => {
//useRouteErrorを用いることで、HTTPレスポンスや原因等を取得することができる。
const error = useRouteError();
//statusはステータスコード(404など)
//statusTextはテキストフレーズ(NotFound など)
//messageはエラー発生原因を示す。
//ただし、エラー情報を可視化がするのが必ずしも正しい訳ではない
// HTTP レスポンスエラーかどうかを確認
if (isRouteErrorResponse(error)) {
// ステータスコードが 404 の場合にカスタムメッセージを表示
if (error.status === 404) {
return (
<h1 >記事が見つかりません</h1>
<p>この記事は非公開か消された可能性があります。</p>
);
}
// その他の HTTP レスポンスエラーの場合
return (
<h1>エラーが発生しました</h1>
<p >{error.status} {error.statusText}</p>
);
}
// HTTP レスポンスエラー以外のエラー(通常の JavaScript エラー)
if (error instanceof Error) {
return (
<h1 className="text-2xl font-bold mb-4">エラーが発生しました</h1>
<p className="text-lg">申し訳ありませんが、問題が発生しました。</p>
<p>{error.message}</p>
);
}
// 未知のエラー
return (
<h1>エラーが発生しました</h1>
<p>予期しない問題が発生しました。</p>
);
};上記のようにすることで、エラー画面を変化させることができる。 注意点として、**hLoaderFunctionやActionFunctionをErrorBoundary中では使えない。** そのため、エラーページは静的ページとし、データを取得しないように注意する。
MetaFuncitonを工夫することで、クローラにエラーを伝えることができる。
export const meta: MetaFunction = ({ matches, data ,error}) => {
// エラー用のメタタグをすべて書く。
if (error) {
return [
{ title: "エラー | KotoriForBlog" },
{ name: "description", content: "ページの読み込み中にエラーが発生しました。" },
];
}
//この後に、通常のメタデータを記述する。
const parentMeta = matches
.flatMap((match) => match.meta ?? [])
.filter((meta) => !("description" in meta));”エラー用のメタタグ”では、LoaderFunctionやActionFunctionから取得できるデータを使わない。エラーが発生していることを最低限伝えることを意識する。
エラー: 不明なセクションタイプ
このセクションは正しく表示できません。
セクションタイプ: chat