megutech

自身の備忘録として主にWEBサーバー周りの技術について投稿しています。

SvelteKitの遅延読み込み中にエラーが発生するとクラッシュする

昨日の記事で無事遅延読み込みは成功するようになりました。

megu-tech.hatenablog.com

しかし新たな問題として、この遅延読み込み処理中にエラーが発生すると、sveltekitがクラッシュすることがあるという現象に見舞われました。

環境

Service Version
@sveltejs/kit 2.5.28
Node.js 20.9.0

コード

遅延処理中に500エラーが発生するようにしています。

import type { PageServerLoad } from './$types';
import axios from 'axios';

export const load: PageServerLoad = async () => {
  return {
    data: axios.get('https://httpstat.us/500'),
  };
};

原因

https://kit.svelte.jp/docs/load#streaming-with-promises

レンダリングの開始時点 (本来この時点で catch される) より前に遅延ロード (lazy-loaded) された promise が失敗し、エラーを処理していない場合、server が "unhandled promise rejection" エラーでクラッシュする可能性があります。

公式ドキュメントに書いてありました。

対策

対策も公式ドキュメントに書いてありました。

fetchを使う

SvelteKit の fetchload 関数で直接使用する場合は SvelteKit がこのケースを処理してくれます。

Axios等を使っている場合、adapterとしてSvelteKitのfetchを使うようにしてあげるといいでしょう。

import type { PageServerLoad } from './$types';

export const load: PageServerLoad = async ({ fetch }) => {
  return {
    data: fetch('https://httpstat.us/500'),
  };
};

握りつぶす

それ以外の promise の場合は、何もしない catch (noop-catch) をアタッチし、処理済であることを明示するだけで十分です。

import type { PageServerLoad } from './$types';
import axios from 'axios';

export const load: PageServerLoad = async () => {
  return {
    data: axios.get('https://httpstat.us/500').catch(() => { error: true }),
  };
};

実施した対応

握りつぶした場合、せっかくフロントで遅延時のエラーを処理する仕組みがSvelteKitにあるにもかかわらず使用できないので、fetchを使う方法を採用しました。

感想

やはり公式ドキュメントしか勝たん。