秋夜孤鸿 發表於 2025-3-29 10:30:00

SvelteKit 最新中文文档教程(14)—— 错误处理

<h2 id="前言">前言</h2>
<p>Svelte,一个语法简洁、入门容易,面向未来的前端框架。</p>
<p>从 Svelte 诞生之初,就备受开发者的喜爱,根据统计,<strong>从 2019 年到 2024 年,连续 6 年一直是开发者最感兴趣的前端框架 No.1</strong>:</p>
<p><img src="https://yayujs-blog.oss-cn-beijing.aliyuncs.com/405488775-48df16b1-939c-489b-8d52-6071869893f0.png"></p>
<p>Svelte 以其独特的编译时优化机制著称,具有<strong>轻量级</strong>、<strong>高性能</strong>、<strong>易上手</strong>等特性,<strong>非常适合构建轻量级 Web 项目</strong>。</p>
<p>为了帮助大家学习 Svelte,我同时搭建了 Svelte 最新的中文文档站点。</p>
<p>如果需要进阶学习,也可以入手我的小册《Svelte 开发指南》,语法篇、实战篇、原理篇三大篇章带你系统掌握 Svelte!</p>
<p>欢迎围观我的“网页版朋友圈”、加入“冴羽·成长陪伴社群”,踏上“前端大佬成长之路”。</p>
<h2 id="错误处理">错误处理</h2>
<p>错误是软件开发中不可避免的事实。SvelteKit 根据错误发生的位置、错误类型以及传入请求的性质,采用不同的方式处理错误。</p>
<h2 id="错误对象">错误对象</h2>
<p>SvelteKit 区分预期错误和意外错误,默认情况下这两种错误都表示为简单的 <code>{ message: string }</code> 对象。</p>
<p>您可以添加额外的属性,比如 <code>code</code> 或跟踪 <code>id</code>,如下面的示例所示。(使用 TypeScript 时,这需要您重新定义 <code>Error</code> 类型,如 类型安全 中所述)。</p>
<h2 id="预期错误">预期错误</h2>
<p>预期错误是使用从 <code>@sveltejs/kit</code> 导入的 <code>error</code> 辅助函数创建的错误:</p>
<pre><code class="language-js">/// file: src/routes/blog//+page.server.js
// @filename: ambient.d.ts
declare module '$lib/server/database' {
export function getPost(slug: string): Promise&lt;{ title: string, content: string } | undefined&gt;
}

// @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 };
}
</code></pre>
<p>这会抛出一个异常,SvelteKit 会捕获该异常,并将响应状态码设置为 404,并渲染一个 <code>+error.svelte</code> 组件,其中 <code>page.error</code> 是一个对象,提供给 <code>error(...)</code> 的第二个参数。</p>
<pre><code class="language-svelte">&lt;!--- file: src/routes/+error.svelte ---&gt;
&lt;script&gt;
import { page } from '$app/state';
&lt;/script&gt;

&lt;h1&gt;{page.error.message}&lt;/h1&gt;
</code></pre>
<blockquote>
<p>[!LEGACY] &gt; <code>$app/state</code> 是在 SvelteKit 2.12 中添加的。如果您使用的是早期版本或正在使用 Svelte 4,请使用 <code>$app/stores</code> 代替。</p>
</blockquote>
<p>如果需要,您可以向错误对象添加额外的属性...</p>
<pre><code class="language-js">import { error } from '@sveltejs/kit';

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

// ---cut---
error(404, {
message: '未找到',
+++code: 'NOT_FOUND'+++
});
</code></pre>
<p>...否则,为了方便起见,您可以将字符串作为第二个参数传递:</p>
<pre><code class="language-js">import { error } from '@sveltejs/kit';
// ---cut---
---error(404, { message: '未找到' });---
+++error(404, '未找到');+++
</code></pre>
<blockquote>
<p>[!NOTE] 在 SvelteKit 1.x 中,您必须自己 <code>throw</code> 这个 <code>error</code></p>
</blockquote>
<h2 id="意外错误">意外错误</h2>
<p>意外错误是处理请求时发生的任何其他异常。由于这些错误可能包含敏感信息,意外错误消息和堆栈跟踪不会暴露给用户。</p>
<p>默认情况下,意外错误会打印到控制台(或在生产环境中打印到服务端日志),而暴露给用户的错误具有通用的形状:</p>
<pre><code class="language-json">{ "message": "内部错误" }
</code></pre>
<p>意外错误将通过 <code>handleError</code> hook 处理,在那里您可以添加自己的错误处理逻辑 — 例如,将错误发送到报告服务,或返回一个自定义错误对象,该对象将成为 <code>$page.error</code>。</p>
<h2 id="响应">响应</h2>
<p>如果错误发生在 <code>handle</code> 或 <code>+server.js</code> 请求处理程序内部,SvelteKit 将根据请求的 <code>Accept</code> 头响应一个回退错误页面或错误对象的 JSON 表示。</p>
<p>您可以通过添加 <code>src/error.html</code> 文件来自定义回退错误页面:</p>
<pre><code class="language-html">&lt;!doctype html&gt;
&lt;html lang="en"&gt;
        &lt;head&gt;
                &lt;meta charset="utf-8" /&gt;
                &lt;title&gt;%sveltekit.error.message%&lt;/title&gt;
        &lt;/head&gt;
        &lt;body&gt;
                &lt;h1&gt;我的自定义错误页面&lt;/h1&gt;
                &lt;p&gt;状态:%sveltekit.status%&lt;/p&gt;
                &lt;p&gt;消息:%sveltekit.error.message%&lt;/p&gt;
        &lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p>SvelteKit 将用相应的值替换 <code>%sveltekit.status%</code> 和 <code>%sveltekit.error.message%</code>。</p>
<p>如果错误发生在渲染页面时的 <code>load</code> 函数内部,SvelteKit 将渲染最接近错误发生位置的 <code>+error.svelte</code> 组件。如果错误发生在 <code>+layout(.server).js</code> 中的 <code>load</code> 函数内部,最近的错误边界是该布局之上的 <code>+error.svelte</code> 文件(不是在它旁边)。</p>
<p>例外情况是当错误发生在根 <code>+layout.js</code> 或 <code>+layout.server.js</code> 内部时,因为根布局通常会包含 <code>+error.svelte</code> 组件。在这种情况下,SvelteKit 使用回退错误页面。</p>
<h2 id="类型安全">类型安全</h2>
<p>如果您使用 TypeScript 并需要自定义错误的形状,您可以通过在您的应用程序中声明一个 <code>App.Error</code> 接口来实现(按照惯例,在 <code>src/app.d.ts</code> 中,尽管它可以存在于 TypeScript 可以"看到"的任何地方):</p>
<pre><code class="language-ts">/// file: src/app.d.ts
declare global {
namespace App {
    interface Error {
+++                        code: string;
      id: string;+++
    }
}
}

export {};
</code></pre>
<p>此接口始终包含 <code>message: string</code> 属性。</p>
<h2 id="进一步阅读">进一步阅读</h2>
<ul>
<li>教程:错误和重定向</li>
<li>教程:Hooks </li>
</ul>
<h2 id="svelte-中文文档">Svelte 中文文档</h2>
<p>点击查看中文文档:SvelteKit 错误处理</p>
<p>系统学习 Svelte,欢迎入手小册《Svelte 开发指南》。语法篇、实战篇、原理篇三大篇章带你系统掌握 Svelte!</p>
<p>此外我还写过 JavaScript 系列、TypeScript 系列、React 系列、Next.js 系列、冴羽答读者问等 14 个系列文章, 全系列文章目录:https://github.com/mqyqingfeng/Blog</p>
<p>欢迎围观我的“网页版朋友圈”、加入“冴羽·成长陪伴社群”,踏上“前端大佬成长之路”。</p><br><br>
来源:https://www.cnblogs.com/yayujs/p/18799223
頁: [1]
查看完整版本: SvelteKit 最新中文文档教程(14)—— 错误处理