Skip to main content

错误

错误是软件开发不可避免的事实。SvelteKit 根据错误发生的位置、错误类型以及传入请求的性质以不同的方式处理错误。

¥Errors are an inevitable fact of software development. SvelteKit handles errors differently depending on where they occur, what kind of errors they are, and the nature of the incoming request.

错误对象(Error objects)

¥Error objects

SvelteKit 区分预期错误和意外错误,默认情况下,两者都表示为简单的 { message: string } 对象。

¥SvelteKit distinguishes between expected and unexpected errors, both of which are represented as simple { message: string } objects by default.

你可以添加其他属性,如 code 或跟踪 id,如以下示例所示。(使用 TypeScript 时需要重新定义 Error 类型,如 类型安全 中所述)。

¥You can add additional properties, like a code or a tracking id, as shown in the examples below. (When using TypeScript this requires you to redefine the Error type as described in type safety).

预期错误(Expected errors)

¥Expected errors

预期错误是使用从 @sveltejs/kit 导入的 error 助手创建的错误:

¥An expected error is one created with the error helper imported from @sveltejs/kit:

src/routes/blog/[slug]/+page.server
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.

@paramstatus The HTTP status code. Must be in the range 400-599.
@parambody An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
@throwsHttpError This error instructs SvelteKit to initiate HTTP error handling.
@throwsError If the provided status is invalid (not between 400 and 599).
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>>
@type{import('./$types').PageServerLoad}
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.

@paramstatus The HTTP status code. Must be in the range 400-599.
@parambody An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
@throwsHttpError This error instructs SvelteKit to initiate HTTP error handling.
@throwsError If the provided status is invalid (not between 400 and 599).
error
(404, {
App.Error.message: stringmessage: '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.

@paramstatus The HTTP status code. Must be in the range 400-599.
@parambody An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
@throwsHttpError This error instructs SvelteKit to initiate HTTP error handling.
@throwsError If the provided status is invalid (not between 400 and 599).
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: PageServerLoadload: 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.

@paramstatus The HTTP status code. Must be in the range 400-599.
@parambody An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
@throwsHttpError This error instructs SvelteKit to initiate HTTP error handling.
@throwsError If the provided status is invalid (not between 400 and 599).
error
(404, {
App.Error.message: stringmessage: 'Not found' }); } return {
post: {
    title: string;
    content: string;
}
post
};
};

这会引发 SvelteKit 捕获的异常,导致它将响应状态代码设置为 404 并渲染 +error.svelte 组件,其中 page.error 是作为 error(...) 的第二个参数提供的对象。

¥This throws an exception that SvelteKit catches, causing it to set the response status code to 404 and render an +error.svelte component, where page.error is the object provided as the second argument to error(...).

src/routes/+error
<script>
	import { page } from '$app/state';
</script>

<h1>{page.error.message}</h1>
<script lang="ts">
	import { page } from '$app/state';
</script>

<h1>{page.error.message}</h1>
Legacy mode

SvelteKit 2.12 中添加了 $app/state。如果你使用的是早期版本或使用 Svelte 4,请改用 $app/stores

¥[!LEGACY] $app/state was added in SvelteKit 2.12. If you’re using an earlier version or are using Svelte 4, use $app/stores instead.

如果需要,你可以向错误对象添加额外的属性...

¥You can add extra properties to the error object if needed...

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.

@paramstatus The HTTP status code. Must be in the range 400-599.
@parambody An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
@throwsHttpError This error instructs SvelteKit to initiate HTTP error handling.
@throwsError If the provided status is invalid (not between 400 and 599).
error
(404, {
App.Error.message: stringmessage: 'Not found', App.Error.code: stringcode: 'NOT_FOUND' });

...否则,为方便起见,你可以将字符串作为第二个参数传递:

¥...otherwise, for convenience, you can pass a string as the second argument:

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.

@paramstatus The HTTP status code. Must be in the range 400-599.
@parambody An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
@throwsHttpError This error instructs SvelteKit to initiate HTTP error handling.
@throwsError If the provided status is invalid (not between 400 and 599).
error
(404, 'Not found');

在 SvelteKit 1.x 中 你必须自己 throw error

¥[!NOTE] In SvelteKit 1.x you had to throw the error yourself

意外错误(Unexpected errors)

¥Unexpected errors

意外错误是处理请求时发生的任何其他异常。由于这些可能包含敏感信息,因此不会向用户公开意外错误消息和堆栈跟踪。

¥An unexpected error is any other exception that occurs while handling a request. Since these can contain sensitive information, unexpected error messages and stack traces are not exposed to users.

默认情况下,意外错误会打印到控制台(或者,在生产中,打印到服务器日志),而向用户公开的错误具有通用形状:

¥By default, unexpected errors are printed to the console (or, in production, your server logs), while the error that is exposed to the user has a generic shape:

{ "message": "Internal Error" }

意外错误将通过 handleError 钩子,你可以在其中添加自己的错误处理 - 例如,将错误发送到报告服务,或返回变为 $page.error 的自定义错误对象。

¥Unexpected errors will go through the handleError hook, where you can add your own error handling — for example, sending errors to a reporting service, or returning a custom error object which becomes $page.error.

响应(Responses)

¥Responses

如果在 handle 内部或 +server.js 请求处理程序内部发生错误,SvelteKit 将根据请求的 Accept 标头以后备错误页面或错误对象的 JSON 表示进行响应。

¥If an error occurs inside handle or inside a +server.js request handler, SvelteKit will respond with either a fallback error page or a JSON representation of the error object, depending on the request’s Accept headers.

你可以通过添加 src/error.html 文件来自定义后备错误页面:

¥You can customise the fallback error page by adding a src/error.html file:

<!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%

¥SvelteKit will replace %sveltekit.status% and %sveltekit.error.message% with their corresponding values.

如果错误在渲染页面时发生在 load 函数内,SvelteKit 将渲染最接近发生错误位置的 +error.svelte 组件。如果错误发生在 +layout(.server).js 中的 load 函数内,则树中最近的错误边界是该布局上方(而不是旁边)的 +error.svelte 文件。

¥If the error instead occurs inside a load function while rendering a page, SvelteKit will render the +error.svelte component nearest to where the error occurred. If the error occurs inside a load function in +layout(.server).js, the closest error boundary in the tree is an +error.svelte file above that layout (not next to it).

例外情况是当错误发生在根 +layout.js+layout.server.js 内部时,因为根布局通常包含 +error.svelte 组件。在这种情况下,SvelteKit 使用后备错误页面。

¥The exception is when the error occurs inside the root +layout.js or +layout.server.js, since the root layout would ordinarily contain the +error.svelte component. In this case, SvelteKit uses the fallback error page.

类型安全(Type safety)

¥Type safety

如果你使用的是 TypeScript 并且需要自定义错误的形状,则可以通过在应用中声明 App.Error 接口来实现(按照惯例,在 src/app.d.ts 中,尽管它可以存在于 TypeScript 可以 ‘see’ 的任何地方):

¥If you’re using TypeScript and need to customize the shape of errors, you can do so by declaring an App.Error interface in your app (by convention, in src/app.d.ts, though it can live anywhere that TypeScript can ‘see’):

src/app.d
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: stringcode: string; App.Error.id: stringid: string; } } } export {};

此接口始终包含 message: string 属性。

¥This interface always includes a message: string property.

进一步阅读(Further reading)

¥Further reading

上一页 下一页