Svelte入門:SvelteKitでのフック処理 -Vol.2-

スポンサーリンク
Svelte入門:SvelteKitでのフック処理 -Vol.2- 用語解説
Svelte入門:SvelteKitでのフック処理 -Vol.2-
この記事は約8分で読めます。
よっしー
よっしー

こんにちは。よっしーです(^^)

今日は、SvelteKitでのフック処.理について解説しています。

スポンサーリンク

背景

SvelteKitでのフック処理について調査する機会がありましたので、その時の内容を備忘として記事に残しました。

共有フック

src/hooks.server.js と src/hooks.client.js に以下を追加できます。

handleError

ローディングまたはレンダリング中に予期しないエラーが発生した場合、この関数が erroreventstatus コード、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 で、eventRequestEvent ではなく NavigationEvent です。

この関数は、予期されるエラー(@sveltejs/kit からインポートされた error 関数で投げられたエラー)に対しては呼び出されません。

開発中に、Svelteコードの構文エラーによってエラーが発生した場合、渡されるエラーにはエラーの位置を強調表示する frame プロパティが追加されます。

handleError が決してエラーを投げないようにしてください。

コード解説

src/hooks.server.js

このコードは、SvelteKitアプリケーションでエラー処理とSentryを使用したエラー追跡の設定を行っています。以下に各部分の説明をします:

  1. Sentryのインポートと初期化:
import * as Sentry from '@sentry/sveltekit';
Sentry.init({/*...*/})
  • Sentryライブラリを ‘@sentry/sveltekit’ からインポートしています。
  • Sentry.init() でSentryを初期化しています。具体的な設定は省略されています。
  1. エラーハンドラ関数の定義:
/** @type {import('@sveltejs/kit').HandleServerError} */
export async function handleError({ error, event, status, message }) {
  // ...
}
  • これはSvelteKitのサーバーサイドエラーハンドラ関数です。
  • 関数は非同期で、エラー、イベント、ステータス、メッセージの情報を受け取ります。
  1. エラーIDの生成:
const errorId = crypto.randomUUID();
  • 各エラーに一意のIDを割り当てるために、crypto.randomUUID() を使用してランダムなUUIDを生成しています。
  1. Sentryへのエラー報告:
Sentry.captureException(error, {
  extra: { event, errorId, status }
});
  • Sentry.captureException() を使用して、エラーをSentryに報告しています。
  • エラーオブジェクトと共に、追加情報(イベント、エラーID、ステータス)も送信しています。
  1. エラーレスポンスの返却:
return {
  message: 'Whoops!',
  errorId
};
  • ユーザーに表示するメッセージと生成したエラーIDを含むオブジェクトを返しています。

このコードは、エラーが発生した際に詳細な情報をSentryに送信し、同時にユーザーにも簡潔なエラーメッセージを提供するものです。エラーIDを含めることで、開発者がユーザーから報告を受けた際に、Sentryで該当するエラーを特定しやすくなります。

src/hooks.client.js

このコードは、先ほど説明したものとよく似ていますが、クライアントサイドのエラー処理を行うものです。主な違いは HandleServerError ではなく HandleClientError を使用している点です。以下に詳細を説明します:

  1. Sentryのインポートと初期化:
import * as Sentry from '@sentry/sveltekit';
Sentry.init({/*...*/})

これは前回と同じです。Sentryをインポートし、初期化しています。

  1. エラーハンドラ関数の定義:
/** @type {import('@sveltejs/kit').HandleClientError} */
export async function handleError({ error, event, status, message }) {
  // ...
}
  • この関数は HandleClientError 型であり、クライアントサイド(ブラウザ側)で発生したエラーを処理します。
  • サーバーサイドエラーハンドラと同様に、エラー、イベント、ステータス、メッセージの情報を受け取ります。
  1. エラーIDの生成:
const errorId = crypto.randomUUID();

これも前回と同じで、各エラーに一意のIDを割り当てています。

  1. Sentryへのエラー報告:
Sentry.captureException(error, {
  extra: { event, errorId, status }
});

サーバーサイドと同様に、エラー情報をSentryに送信しています。

  1. エラーレスポンスの返却:
return {
  message: 'Whoops!',
  errorId
};

ユーザーに表示するメッセージとエラーIDを返しています。

このクライアントサイドエラーハンドラの主な目的は以下の通りです:

  1. ブラウザで発生したエラーをキャッチする
  2. 各エラーに一意のIDを割り当てる
  3. エラー情報をSentryに送信し、後で分析できるようにする
  4. ユーザーに簡潔なエラーメッセージを提供する

クライアントサイドでこのようなエラーハンドリングを実装することで、JavaScriptの実行エラーやネットワークエラーなど、ブラウザで発生する様々な問題を捕捉し、追跡することができます。これにより、開発者はユーザーが経験した問題をより効果的に理解し、デバッグすることができます。

サーバーサイドとクライアントサイドの両方でエラーハンドリングを実装することで、アプリケーション全体の堅牢性が向上し、問題の迅速な特定と解決が可能になります。

おわりに

今日は、 SvelteKitでのフック処理について解説しました。

よっしー
よっしー

何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。

それでは、また明日お会いしましょう(^^)

コメント

タイトルとURLをコピーしました