前言
Svelte,一個語法簡潔、入門容易,面向未來的前端框架。
從 Svelte 誕生之初,就備受開發者的喜愛,根據統計,從 2019 年到 2024 年,連續 6 年一直是開發者最感興趣的前端框架 No.1:
Svelte 以其獨特的編譯時優化機制著稱,具有輕量級、高性能、易上手等特性,非常適合構建輕量級 Web 項目。
為了幫助大家學習 Svelte,我同時搭建了 Svelte 最新的中文文檔站點。
如果需要進階學習,也可以入手我的小冊《Svelte 開發指南》,語法篇、實戰篇、原理篇三大篇章帶你係統掌握 Svelte!
歡迎圍觀我的“網頁版朋友圈”、加入“冴羽·成長陪伴社羣”,踏上“前端大佬成長之路”。
錯誤處理
錯誤是軟件開發中不可避免的事實。SvelteKit 根據錯誤發生的位置、錯誤類型以及傳入請求的性質,採用不同的方式處理錯誤。
錯誤對象
SvelteKit 區分預期錯誤和意外錯誤,默認情況下這兩種錯誤都表示為簡單的 { message: string } 對象。
您可以添加額外的屬性,比如 code 或跟蹤 id,如下面的示例所示。(使用 TypeScript 時,這需要您重新定義 Error 類型,如 類型安全 中所述)。
預期錯誤
預期錯誤是使用從 @sveltejs/kit 導入的 error 輔助函數創建的錯誤:
/// file: src/routes/blog/[slug]/+page.server.js
// @filename: ambient.d.ts
declare module '$lib/server/database' {
export function getPost(slug: string): Promise<{ title: string, content: string } | undefined>
}
// @filename: index.js
// ---cut---
import { error } from '@sveltejs/kit';
import * as db from '$lib/server/database';
/** @type {import('./$types').PageServerLoad} */
export async function load({ params }) {
const post = await db.getPost(params.slug);
if (!post) {
error(404, {
message: '未找到'
});
}
return { post };
}
這會拋出一個異常,SvelteKit 會捕獲該異常,並將響應狀態碼設置為 404,並渲染一個 +error.svelte 組件,其中 page.error 是一個對象,提供給 error(...) 的第二個參數。
<!--- file: src/routes/+error.svelte --->
<script>
import { page } from '$app/state';
</script>
<h1>{page.error.message}</h1>
[!LEGACY] >$app/state是在 SvelteKit 2.12 中添加的。如果您使用的是早期版本或正在使用 Svelte 4,請使用$app/stores代替。
如果需要,您可以向錯誤對象添加額外的屬性...
import { error } from '@sveltejs/kit';
declare global {
namespace App {
interface Error {
message: string;
code: string;
}
}
}
// ---cut---
error(404, {
message: '未找到',
+++code: 'NOT_FOUND'+++
});
...否則,為了方便起見,您可以將字符串作為第二個參數傳遞:
import { error } from '@sveltejs/kit';
// ---cut---
---error(404, { message: '未找到' });---
+++error(404, '未找到');+++
[!NOTE] 在 SvelteKit 1.x 中,您必須自己throw這個error
意外錯誤
意外錯誤是處理請求時發生的任何其他異常。由於這些錯誤可能包含敏感信息,意外錯誤消息和堆棧跟蹤不會暴露給用户。
默認情況下,意外錯誤會打印到控制枱(或在生產環境中打印到服務端日誌),而暴露給用户的錯誤具有通用的形狀:
{ "message": "內部錯誤" }
意外錯誤將通過 handleError hook 處理,在那裏您可以添加自己的錯誤處理邏輯 — 例如,將錯誤發送到報告服務,或返回一個自定義錯誤對象,該對象將成為 $page.error。
響應
如果錯誤發生在 handle 或 +server.js 請求處理程序內部,SvelteKit 將根據請求的 Accept 頭響應一個回退錯誤頁面或錯誤對象的 JSON 表示。
您可以通過添加 src/error.html 文件來自定義回退錯誤頁面:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>%sveltekit.error.message%</title>
</head>
<body>
<h1>我的自定義錯誤頁面</h1>
<p>狀態:%sveltekit.status%</p>
<p>消息:%sveltekit.error.message%</p>
</body>
</html>
SvelteKit 將用相應的值替換 %sveltekit.status% 和 %sveltekit.error.message%。
如果錯誤發生在渲染頁面時的 load 函數內部,SvelteKit 將渲染最接近錯誤發生位置的 +error.svelte 組件。如果錯誤發生在 +layout(.server).js 中的 load 函數內部,最近的錯誤邊界是該佈局之上的 +error.svelte 文件(不是在它旁邊)。
例外情況是當錯誤發生在根 +layout.js 或 +layout.server.js 內部時,因為根佈局通常會包含 +error.svelte 組件。在這種情況下,SvelteKit 使用回退錯誤頁面。
類型安全
如果您使用 TypeScript 並需要自定義錯誤的形狀,您可以通過在您的應用程序中聲明一個 App.Error 接口來實現(按照慣例,在 src/app.d.ts 中,儘管它可以存在於 TypeScript 可以"看到"的任何地方):
/// file: src/app.d.ts
declare global {
namespace App {
interface Error {
+++ code: string;
id: string;+++
}
}
}
export {};
此接口始終包含 message: string 屬性。
進一步閲讀
- 教程:錯誤和重定向
- 教程:Hooks
Svelte 中文文檔
點擊查看中文文檔:SvelteKit 錯誤處理
系統學習 Svelte,歡迎入手小冊《Svelte 開發指南》。語法篇、實戰篇、原理篇三大篇章帶你係統掌握 Svelte!
此外我還寫過 JavaScript 系列、TypeScript 系列、React 系列、Next.js 系列、冴羽答讀者問等 14 個系列文章, 全系列文章目錄:https://github.com/mqyqingfeng/Blog
歡迎圍觀我的“網頁版朋友圈”、加入“冴羽·成長陪伴社羣”,踏上“前端大佬成長之路”。