动态

详情 返回 返回

SvelteKit 最新中文文檔教程(14)—— 錯誤處理 - 动态 详情

前言

Svelte,一個語法簡潔、入門容易,面向未來的前端框架。

從 Svelte 誕生之初,就備受開發者的喜愛,根據統計,從 2019 年到 2024 年,連續 6 年一直是開發者最感興趣的前端框架 No.1

image.png

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

歡迎圍觀我的“網頁版朋友圈”、加入“冴羽·成長陪伴社羣”,踏上“前端大佬成長之路”。

Add a new 评论

Some HTML is okay.