SvelteKit SSR fetch失败:Express环境下TypeScript无有效栈追踪如何解决?
优化SvelteKit SSR错误排查的方案
1. 启用源映射还原栈追踪
SvelteKit生产环境默认关闭源映射,导致栈追踪仅显示编译后JS文件路径。在svelte.config.js中强制开启生产环境源映射:
import adapter from '@sveltejs/adapter-node'; export default { kit: { adapter: adapter(), vite: { build: { sourcemap: true // 强制生成源映射文件 } } } };
同时确保Docker构建流程中保留.map文件,不要在构建后执行清理操作,这样栈追踪就能关联到对应的TypeScript源文件和具体行号。
2. 全局包装fetch捕获请求上下文
在src/hooks.server.ts中包装全局fetch方法,将请求URL、配置等信息附加到错误对象中:
function wrappedFetch(originalFetch: typeof fetch) { return async (input: RequestInfo | URL, init?: RequestInit) => { const url = typeof input === 'string' ? input : input.toString(); try { return await originalFetch(input, init); } catch (error) { // 给错误附加请求详情 (error as any).fetchUrl = url; (error as any).fetchOptions = init; throw error; } }; } export async function handle({ event, resolve }) { event.fetch = wrappedFetch(event.fetch); return resolve(event); }
3. 增强Server端错误处理钩子
利用handleServerError钩子整合页面路由、请求详情和栈追踪,输出结构化日志:
import type { HandleServerError } from '@sveltejs/kit'; export const handleServerError: HandleServerError = async ({ error, event }) => { const route = event.url.pathname; const fetchUrl = (error as any).fetchUrl; const fetchOptions = (error as any).fetchOptions; // 打印详细错误信息 console.error(`[SSR错误] 页面路由: ${route}`); if (fetchUrl) { console.error(`请求API地址: ${fetchUrl}`); console.error(`请求配置: ${JSON.stringify(fetchOptions)}`); } console.error(`错误栈追踪:`, error.stack); return { message: '服务器内部错误', code: (error as any).code || 'UNKNOWN_ERROR' }; };
4. 局部load函数添加错误标记
在关键页面的load函数中添加try/catch,明确标记当前页面信息:
// src/routes/dashboard/+page.server.ts export async function load({ fetch, params }) { try { const res = await fetch(`/api/dashboard/${params.id}`); if (!res.ok) throw new Error(`API响应异常: ${res.status}`); return { data: await res.json() }; } catch (error) { // 附加当前页面标识 (error as any).pageRoute = '/dashboard/[id]'; (error as any).pageParams = params; throw error; } }
5. 确保Express服务器传递原始错误
自定义Express服务器时,不要在错误中间件中覆盖原始错误,完整输出错误信息:
// server.js import express from 'express'; import { handler } from './build/handler.js'; const app = express(); app.use(handler); // 自定义错误中间件 app.use((err, req, res, next) => { console.error(`Express错误详情:`, err); res.status(500).send('服务器异常'); }); app.listen(3000);
完成以上配置后,fetch失败时你将在日志中获取到:
- 触发错误的页面路由
- 失败的API请求URL及配置
- 关联到TypeScript源文件的完整栈追踪
- 具体load函数所在的页面标识
内容的提问来源于stack exchange,提问作者Mikko Ohtamaa
相关产品推荐
相关产品推荐

