昨日の記事で無事遅延読み込みは成功するようになりました。
しかし新たな問題として、この遅延読み込み処理中にエラーが発生すると、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 の
fetchをload関数で直接使用する場合は 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を使う方法を採用しました。
感想
やはり公式ドキュメントしか勝たん。