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

<svelte:boundary>

<svelte:boundary onerror={handler}>...</svelte:boundary>

Границы позволяют «отделить» части вашего приложения, чтобы вы могли:

  • отображать интерфейс, который должен показываться во время первоначального выполнения await-выражений
  • обрабатывать ошибки, возникающие при рендеринге или выполнении эффектов, и предоставлять интерфейс для отображения при возникновении ошибки

Если граница обрабатывает ошибку (с помощью сниппета failed или обработчика onerror, или обоих), её текущее содержимое будет удалено.

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

Этот сниппет будет показан при первом создании границы и останется видимым до тех пор, пока все выражения await внутри границы не разрешатся (демонстрация):

<svelte:boundary>
<p>{await delayed('привет!')}</p>
{#snippet pending()}
<p>загрузка...</p>
{/snippet}
</svelte:boundary>

Если предусмотрен сниппет failed, он будет отображаться при возникновении ошибки внутри границы, получая доступ к объекту error и функции reset для повторного создания содержимого (демонстрация):

<svelte:boundary>
<FlakyComponent />
{#snippet failed(error, reset)}
<button onclick={reset}>упс! попробовать ещё раз</button>
{/snippet}
</svelte:boundary>

Если предоставлена функция onerror, она будет вызвана с теми же двумя аргументами: error и reset. Это полезно для отслеживания ошибок с помощью сервиса отчётов об ошибках…

<svelte:boundary onerror={(e) => report(e)}>
...
</svelte:boundary>

…или для использования error и reset за пределами самой границы:

<script>
let error = $state(null);
let reset = $state(() => {});
function onerror(e, r) {
error = e;
reset = r;
}
</script>
<svelte:boundary {onerror}>
<FlakyComponent />
</svelte:boundary>
{#if error}
<button onclick={() => {
error = null;
reset();
}}>
упс! попробовать ещё раз
</button>
{/if}

Если ошибка происходит внутри функции onerror (или если вы повторно выбрасываете ошибку), она будет обработана родительской границей, если таковая существует.

По умолчанию границы ошибок никак не влияют на сервер — если во время рендеринга возникает ошибка, весь рендеринг завершится неудачей.

Начиная с версии 5.51 вы можете управлять этим поведением для границ ошибок с помощью сниппета failed, вызвав функцию render(...) с параметром transformError.

Функция transformError должна возвращать объект, который можно сериализовать в JSON. Этот объект будет использован для рендеринга сниппета failed. Он будет сериализован и применён для гидратации сниппета в браузере:

import { render } from 'svelte/server';
import App from './App.svelte';
const { head, body } = await render(App, {
transformError: (error) => {
// логируем оригинальную ошибку вместе со стек-трейсом...
console.error(error);
// ...и возвращаем очищенную, удобную для пользователя ошибку,
// которая будет отображена в сниппете `failed`
return {
message: 'An error occurred!'
};
};
});

Если transformError выбросит исключение (или перевыбросит ошибку), то вызов render(...) в целом завершится неудачей с этой ошибкой.

Если у границы ошибок задан обработчик onerror, он будет вызван во время гидратации с десериализованным объектом ошибки.

Функции mount и hydrate также принимают опцию transformError, которая по умолчанию является функцией идентичности (возвращает переданное значение без изменений). Как и в случае с render, эта функция преобразует ошибку времени рендеринга перед тем, как она будет передана в сниппет failed или обработчик onerror.