錯誤
錯誤是軟體開發中不可避免的事實。SvelteKit 根據錯誤發生的位置、錯誤的種類以及傳入請求的性質,以不同的方式處理錯誤。
錯誤物件
SvelteKit 區分預期錯誤和非預期錯誤,兩者預設都以簡單的 { message: string }
物件表示。
您可以新增額外的屬性,例如 code
或追蹤 id
,如下面的範例所示。(當使用 TypeScript 時,這需要您重新定義 Error
類型,如型別安全中所述)。
預期錯誤
預期錯誤是使用從 @sveltejs/kit
導入的 error
輔助函數建立的錯誤。
import { function error(status: number, body: App.Error): never (+1 overload)
Throws an error with a HTTP status code and an optional message.
When called during request handling, this will cause SvelteKit to
return an error response without invoking handleError
.
Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.
error } from '@sveltejs/kit';
import * as module "$lib/server/database"
db from '$lib/server/database';
/** @type {import('./$types').PageServerLoad} */
export async function function load(event: ServerLoadEvent<Record<string, any>, Record<string, any>, string | null>): MaybePromise<void | Record<string, any>>
load({ params: Record<string, any>
The parameters of the current route - e.g. for a route like /blog/[slug]
, a { slug: string }
object
params }) {
const const post: {
title: string;
content: string;
} | undefined
post = await module "$lib/server/database"
db.function getPost(slug: string): Promise<{
title: string;
content: string;
} | undefined>
getPost(params: Record<string, any>
The parameters of the current route - e.g. for a route like /blog/[slug]
, a { slug: string }
object
params.slug);
if (!const post: {
title: string;
content: string;
} | undefined
post) {
function error(status: number, body: App.Error): never (+1 overload)
Throws an error with a HTTP status code and an optional message.
When called during request handling, this will cause SvelteKit to
return an error response without invoking handleError
.
Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.
error(404, {
App.Error.message: string
message: 'Not found'
});
}
return { post: {
title: string;
content: string;
}
post };
}
import { function error(status: number, body: App.Error): never (+1 overload)
Throws an error with a HTTP status code and an optional message.
When called during request handling, this will cause SvelteKit to
return an error response without invoking handleError
.
Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.
error } from '@sveltejs/kit';
import * as module "$lib/server/database"
db from '$lib/server/database';
import type { type PageServerLoad = (event: ServerLoadEvent<Record<string, any>, Record<string, any>, string | null>) => MaybePromise<void | Record<string, any>>
PageServerLoad } from './$types';
export const const load: PageServerLoad
load: type PageServerLoad = (event: ServerLoadEvent<Record<string, any>, Record<string, any>, string | null>) => MaybePromise<void | Record<string, any>>
PageServerLoad = async ({ params: Record<string, any>
The parameters of the current route - e.g. for a route like /blog/[slug]
, a { slug: string }
object
params }) => {
const const post: {
title: string;
content: string;
} | undefined
post = await module "$lib/server/database"
db.function getPost(slug: string): Promise<{
title: string;
content: string;
} | undefined>
getPost(params: Record<string, any>
The parameters of the current route - e.g. for a route like /blog/[slug]
, a { slug: string }
object
params.slug);
if (!const post: {
title: string;
content: string;
} | undefined
post) {
function error(status: number, body: App.Error): never (+1 overload)
Throws an error with a HTTP status code and an optional message.
When called during request handling, this will cause SvelteKit to
return an error response without invoking handleError
.
Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.
error(404, {
App.Error.message: string
message: 'Not found'
});
}
return { post: {
title: string;
content: string;
}
post };
};
這會拋出 SvelteKit 捕獲的例外,導致它將回應狀態碼設定為 404 並呈現 +error.svelte
元件,其中 $page.error
是作為 error(...)
的第二個參數提供的物件。
<script>
import { page } from '$app/stores';
</script>
<h1>{$page.error.message}</h1>
如果需要,您可以將額外的屬性新增至錯誤物件...
function error(status: number, body: App.Error): never (+1 overload)
Throws an error with a HTTP status code and an optional message.
When called during request handling, this will cause SvelteKit to
return an error response without invoking handleError
.
Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.
error(404, {
App.Error.message: string
message: 'Not found',
App.Error.code: string
code: 'NOT_FOUND'
});
...否則,為了方便起見,您可以將字串作為第二個參數傳遞
error(404, { message: 'Not found' });
function error(status: number, body?: {
message: string;
} extends App.Error ? App.Error | string | undefined : never): never (+1 overload)
Throws an error with a HTTP status code and an optional message.
When called during request handling, this will cause SvelteKit to
return an error response without invoking handleError
.
Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.
error(404, 'Not found');
在 SvelteKit 1.x 中,您必須自己
throw
error
非預期錯誤
非預期錯誤是在處理請求時發生的任何其他例外。由於這些錯誤可能包含敏感資訊,因此非預期錯誤訊息和堆疊追蹤不會向使用者公開。
預設情況下,非預期錯誤會列印到主控台(或在生產環境中,列印到您的伺服器日誌),而向使用者公開的錯誤則具有通用形狀
{ "message": "Internal Error" }
非預期錯誤將會通過 handleError
鉤子,您可以在其中新增自己的錯誤處理 — 例如,將錯誤傳送到回報服務,或傳回自訂錯誤物件,該物件會變成 $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>My custom error page</h1>
<p>Status: %sveltekit.status%</p>
<p>Message: %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 可以「看到」的任何位置)
declare global {
namespace App {
interface interface App.Error
Defines the common shape of expected and unexpected errors. Expected errors are thrown using the error
function. Unexpected errors are handled by the handleError
hooks which should return this shape.
Error {
App.Error.code: string
code: string;
App.Error.id: string
id: string;
}
}
}
export {};
此介面始終包含 message: string
屬性。