こんにちは。よっしーです(^^)
今日は、SvelteKitでのフック処.理について解説しています。
背景
SvelteKitでのフック処理について調査する機会がありましたので、その時の内容を備忘として記事に残しました。
共有フック
src/hooks.server.js と src/hooks.client.js に以下を追加できます。
handleError
ローディングまたはレンダリング中に予期しないエラーが発生した場合、この関数が error
、event
、status
コード、message
とともに呼び出されます。これにより以下の2つのことが可能になります:
- エラーをログに記録できます
- ユーザーに安全に表示できるエラーのカスタム表現を生成できます。メッセージやスタックトレースなどの機密情報を省略します。返される値(デフォルトは
{ message }
)は$page.error
の値となります。
あなたのコード(またはあなたのコードから呼び出されるライブラリコード)から投げられたエラーの場合、ステータスは500で、メッセージは “Internal Error” になります。error.message
にはユーザーに公開すべきでない機密情報が含まれている可能性がありますが、message
は安全です(ただし、一般的なユーザーにとっては意味をなしません)。
$page.error
オブジェクトにタイプセーフな方法でより多くの情報を追加するには、App.Error
インターフェース(message: string
を含む必要があります。これは適切なフォールバック動作を保証するためです)を宣言してカスタマイズできます。これにより、例えば、ユーザーが技術サポートスタッフとのやり取りで引用するためのトラッキングIDを追加できます:
src/app.d.ts
declare global {
namespace App {
interface Error {
message: string;
errorId: string;
}
}
}
export {};
src/hooks.server.js
import * as Sentry from '@sentry/sveltekit';
Sentry.init({/*...*/})
/** @type {import('@sveltejs/kit').HandleServerError} */
export async function handleError({ error, event, status, message }) {
const errorId = crypto.randomUUID();
// example integration with https://sentry.io/
Sentry.captureException(error, {
extra: { event, errorId, status }
});
return {
message: 'Whoops!',
errorId
};
}
src/hooks.client.js
import * as Sentry from '@sentry/sveltekit';
Sentry.init({/*...*/})
/** @type {import('@sveltejs/kit').HandleClientError} */
export async function handleError({ error, event, status, message }) {
const errorId = crypto.randomUUID();
// example integration with https://sentry.io/
Sentry.captureException(error, {
extra: { event, errorId, status }
});
return {
message: 'Whoops!',
errorId
};
}
src/hooks.client.js
では、handleError
の型は HandleServerError
ではなく HandleClientError
で、event
は RequestEvent
ではなく NavigationEvent
です。
この関数は、予期されるエラー(@sveltejs/kit
からインポートされた error
関数で投げられたエラー)に対しては呼び出されません。
開発中に、Svelteコードの構文エラーによってエラーが発生した場合、渡されるエラーにはエラーの位置を強調表示する frame
プロパティが追加されます。
handleError
が決してエラーを投げないようにしてください。
コード解説
src/hooks.server.js
このコードは、SvelteKitアプリケーションでエラー処理とSentryを使用したエラー追跡の設定を行っています。以下に各部分の説明をします:
- Sentryのインポートと初期化:
import * as Sentry from '@sentry/sveltekit';
Sentry.init({/*...*/})
- Sentryライブラリを ‘@sentry/sveltekit’ からインポートしています。
Sentry.init()
でSentryを初期化しています。具体的な設定は省略されています。
- エラーハンドラ関数の定義:
/** @type {import('@sveltejs/kit').HandleServerError} */
export async function handleError({ error, event, status, message }) {
// ...
}
- これはSvelteKitのサーバーサイドエラーハンドラ関数です。
- 関数は非同期で、エラー、イベント、ステータス、メッセージの情報を受け取ります。
- エラーIDの生成:
const errorId = crypto.randomUUID();
- 各エラーに一意のIDを割り当てるために、
crypto.randomUUID()
を使用してランダムなUUIDを生成しています。
- Sentryへのエラー報告:
Sentry.captureException(error, {
extra: { event, errorId, status }
});
Sentry.captureException()
を使用して、エラーをSentryに報告しています。- エラーオブジェクトと共に、追加情報(イベント、エラーID、ステータス)も送信しています。
- エラーレスポンスの返却:
return {
message: 'Whoops!',
errorId
};
- ユーザーに表示するメッセージと生成したエラーIDを含むオブジェクトを返しています。
このコードは、エラーが発生した際に詳細な情報をSentryに送信し、同時にユーザーにも簡潔なエラーメッセージを提供するものです。エラーIDを含めることで、開発者がユーザーから報告を受けた際に、Sentryで該当するエラーを特定しやすくなります。
src/hooks.client.js
このコードは、先ほど説明したものとよく似ていますが、クライアントサイドのエラー処理を行うものです。主な違いは HandleServerError
ではなく HandleClientError
を使用している点です。以下に詳細を説明します:
- Sentryのインポートと初期化:
import * as Sentry from '@sentry/sveltekit';
Sentry.init({/*...*/})
これは前回と同じです。Sentryをインポートし、初期化しています。
- エラーハンドラ関数の定義:
/** @type {import('@sveltejs/kit').HandleClientError} */
export async function handleError({ error, event, status, message }) {
// ...
}
- この関数は
HandleClientError
型であり、クライアントサイド(ブラウザ側)で発生したエラーを処理します。 - サーバーサイドエラーハンドラと同様に、エラー、イベント、ステータス、メッセージの情報を受け取ります。
- エラーIDの生成:
const errorId = crypto.randomUUID();
これも前回と同じで、各エラーに一意のIDを割り当てています。
- Sentryへのエラー報告:
Sentry.captureException(error, {
extra: { event, errorId, status }
});
サーバーサイドと同様に、エラー情報をSentryに送信しています。
- エラーレスポンスの返却:
return {
message: 'Whoops!',
errorId
};
ユーザーに表示するメッセージとエラーIDを返しています。
このクライアントサイドエラーハンドラの主な目的は以下の通りです:
- ブラウザで発生したエラーをキャッチする
- 各エラーに一意のIDを割り当てる
- エラー情報をSentryに送信し、後で分析できるようにする
- ユーザーに簡潔なエラーメッセージを提供する
クライアントサイドでこのようなエラーハンドリングを実装することで、JavaScriptの実行エラーやネットワークエラーなど、ブラウザで発生する様々な問題を捕捉し、追跡することができます。これにより、開発者はユーザーが経験した問題をより効果的に理解し、デバッグすることができます。
サーバーサイドとクライアントサイドの両方でエラーハンドリングを実装することで、アプリケーション全体の堅牢性が向上し、問題の迅速な特定と解決が可能になります。
おわりに
今日は、 SvelteKitでのフック処理について解説しました。
何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。
それでは、また明日お会いしましょう(^^)
コメント