使用 Sentry 进行错误监控和性能追踪。
配置文件
Sentry 通过 3 个配置文件初始化:
sentry.client.config.ts — 客户端,使用 NEXT_PUBLIC_SENTRY_DSN
sentry.server.config.ts — 服务端,使用 SENTRY_DSN(无 NEXT_PUBLIC 前缀)
sentry.edge.config.ts — Edge runtime,使用 SENTRY_DSN
初始化
仅在 SENTRY_DSN 存在且非开发环境时初始化:
// sentry.client.config.ts
import * as Sentry from '@sentry/nextjs';
if (process.env.NEXT_PUBLIC_SENTRY_DSN && process.env.NODE_ENV !== 'development') {
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
tracesSampleRate: 0.1,
environment: process.env.NODE_ENV,
beforeSend(event) {
const message = event.exception?.values?.[0]?.value ?? '';
const type = event.exception?.values?.[0]?.type ?? '';
// 过滤掉已知的非关键错误
const ignoredPatterns = [
'NEXT_REDIRECT',
'NEXT_NOT_FOUND',
'AbortError',
'ChunkLoadError',
'Failed to fetch dynamically imported module',
'ResizeObserver loop',
];
if (ignoredPatterns.some((p) => message.includes(p) || type.includes(p))) {
return null;
}
return event;
},
});
}
客户端使用 NEXT_PUBLIC_SENTRY_DSN,服务端和 Edge 使用 SENTRY_DSN(无 NEXT_PUBLIC 前缀)。
手动捕获
try {
await riskyOperation();
} catch (error) {
Sentry.captureException(error, {
tags: { feature: 'generator' },
extra: { imageId: currentImage.id },
});
}
用户上下文
// 登录后设置用户信息
Sentry.setUser({
id: user.id,
email: user.email,
});
// 登出时清除
Sentry.setUser(null);
面包屑
Sentry.addBreadcrumb({
category: 'user-action',
message: 'Applied filter',
level: 'info',
data: {
filterId: selectedFilter.id,
},
});
最佳实践
- 为错误添加有意义的 tags 和 extra 数据
- 登录后设置用户上下文
- 在关键操作前后添加面包屑