You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Svelte中如何在async函数内调用error()方法?

解决SvelteKit中async函数内调用error()触发未处理Promise拒绝的问题

问题说明

在SvelteKit的async函数里调用error()时,会抛出未处理Promise拒绝错误,报错内容如下:

node:internal/process/promises:289
            triggerUncaughtException(err, true /* fromPromise */);
            ^

[UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "#<Redirect>".] {
  code: 'ERR_UNHANDLED_REJECTION'
}

Node.js v20.11.0

复现场景

案例1:组件内直接定义async函数调用error()

<script lang="ts">
    import { error } from '@sveltejs/kit';

    const tst = async() => error( 400, 'My error message' );

    tst();
</script>

案例2:在onMount的async回调中调用error()

<script lang="ts">
    import { error } from '@sveltejs/kit';
    import { onMount } from 'svelte';

    onMount( async function() 
    {
        error( 400, 'My error message' );
    } );
</script>

此时浏览器控制台会出现uncaught (in promise)的同类错误。

需求:保留async函数逻辑,同时避免在每个async调用外重复写try..catch。

解决方案

1. 用SvelteKit的load函数处理错误(推荐)

error()原本就是为页面/布局的load函数或服务器端逻辑设计的,这类场景下框架会自动处理错误,无需手动catch。如果业务逻辑允许,把代码迁移到+page.ts或+layout.ts的load函数中:

// src/routes/+page.ts
import type { PageLoad } from './$types';
import { error } from '@sveltejs/kit';

export const load: PageLoad = async ({ params }) => {
  // 模拟异步操作
  const data = await fetchSomeData();
  if (!data) {
    error(400, 'My error message');
  }
  return { data };
};

2. 封装全局错误处理工具函数

如果必须在组件async函数(比如onMount)中调用error(),可以封装一个自动捕获错误的工具函数,减少重复代码:

// src/lib/utils.ts
import { error } from '@sveltejs/kit';

export async function withErrorHandling<T>(fn: () => Promise<T>) {
  try {
    return await fn();
  } catch (err) {
    if (err instanceof Error) {
      error(400, err.message);
    } else {
      error(400, 'Unknown error');
    }
  }
}

组件内使用示例:

<script lang="ts">
    import { onMount } from 'svelte';
    import { withErrorHandling } from '$lib/utils';

    onMount(() => withErrorHandling(async () => {
      // 你的异步业务逻辑
      const res = await fetch('/api/data');
      if (!res.ok) {
        throw new Error('Request failed');
      }
      // 也可以直接调用SvelteKit的error
      // error(400, 'My error message');
    }));
</script>

3. 配置全局错误处理钩子

在src/hooks.server.ts(服务器端)或src/hooks.client.ts(客户端)中设置全局错误处理钩子,兜底捕获未处理的错误:

// src/hooks.client.ts
import type { HandleError } from '@sveltejs/kit';

export const handleError: HandleError = async ({ error, event }) => {
  // 可在此处添加错误日志上报逻辑
  console.error('Client error:', error, event);
  // 返回自定义错误提示给用户
  return {
    message: 'Oops! Something went wrong.'
  };
};

内容的提问来源于stack exchange,提问作者Z0q

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 08:32:32