Перейти к содержимому

Ошибки

Ошибки — неизбежная часть разработки программного обеспечения. SvelteKit обрабатывает ошибки по-разному в зависимости от того, где они произошли, какого они типа и какова природа входящего запроса.

SvelteKit различает ожидаемые и неожиданные ошибки. По умолчанию оба типа представляются простыми объектами вида { message: string }.

Вы можете добавлять дополнительные свойства, например code или идентификатор для отслеживания id, как показано в примерах ниже. (При использовании TypeScript для этого потребуется переопределить тип Error, как описано в разделе Безопасность типов).

Ожидаемая ошибка — это ошибка, созданная с помощью вспомогательной функции error, импортируемой из @sveltejs/kit:

src/routes/blog/[slug]/+page.server.js
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: 'Not found'
});
}
return { post };
}

Это выбрасывает исключение, которое SvelteKit перехватывает, в результате чего он устанавливает код статуса ответа 404 и отображает компонент +error.svelte, в котором page.error будет объектом, переданным вторым аргументом в функцию error(...).

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

$app/state был добавлен в SvelteKit 2.12. Если вы используете более раннюю версию или работаете с Svelte 4, используйте вместо этого $app/stores.

Вы можете добавлять дополнительные свойства в объект ошибки, если это необходимо…

error(404, {
message: 'Not found',
code: 'NOT_FOUND'
});

…в противном случае, для удобства, вы можете передать строку вторым аргументом:

error(404, { message: 'Not found' });
error(404, 'Not found');

Неожиданная ошибка — это любое другое исключение, которое возникает во время обработки запроса. Поскольку такие ошибки могут содержать конфиденциальную информацию, сообщения о неожиданных ошибках и трассировки стека не показываются пользователям.

По умолчанию неожиданные ошибки выводятся в консоль (или, в продакшене, в логи вашего сервера), а пользователю отображается ошибка в обобщённом виде:

{ "message": "Internal Error" }

Неожиданные ошибки проходят через хук handleError, где вы можете добавить собственную обработку ошибок — например, отправлять ошибки в сервис отчётности или возвращать собственный объект ошибки, который затем станет доступен как page.error.

Если ошибка возникает внутри handle или внутри обработчика запроса +server.js, SvelteKit ответит либо резервной страницей ошибки, либо JSON-представлением объекта ошибки — в зависимости от заголовка Accept входящего запроса.

Вы можете настроить резервную страницу ошибки, добавив файл src/error.html:

<!DOCTYPE html>
<html lang="ru">
<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, ближайший к месту возникновения ошибки. Если ошибка возникает внутри функции load в файле +layout(.server).js, то ближайшей границей ошибки в дереве будет файл +error.svelte, расположенный выше этого layout (не рядом с ним).

Исключение составляет случай, когда ошибка происходит внутри корневого +layout.js или +layout.server.js, поскольку корневой layout обычно содержит компонент +error.svelte. В таком случае SvelteKit использует резервную страницу ошибки.

Если вы используете TypeScript и хотите настроить форму ошибок, вы можете сделать это, объявив интерфейс App.Error в вашем приложении (по соглашению — в файле src/app.d.ts, хотя он может находиться в любом месте, где TypeScript его увидит):

declare global {
namespace App {
interface Error {
code: string;
id: string;
}
}
}
export {};

Этот интерфейс всегда включает свойство message: string.