mcpField
A
add-error-tracking

add-error-tracking

github.com/gotempsh开发87641 次安装今天更新
代码仓库

关于 add-error-tracking

add-error-tracking 是一项将 Temps 错误跟踪接入应用的技能,适合需要在多种语言和框架中配置错误报告的开发者。它使用兼容 Sentry 的 DSN 和官方 Sentry SDK,并为浏览器项目说明隧道配置。

主要功能

  1. 01按代码库识别平台
  2. 02使用官方 Sentry SDK 配置
  3. 03通过环境变量设置 DSN
  4. 04为浏览器 SDK 配置隧道
  5. 05提供多语言平台设置示例
  6. 06捕获自定义异常

适用场景

  1. 01为 Next.js 应用接入 Temps 错误跟踪
  2. 02在 Node.js 或 Python 服务中报告异常
  3. 03为浏览器应用配置同源事件隧道
  4. 04为移动端或后端项目配置错误 SDK

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/gotempsh/temps --skill add-error-tracking

安装后在 Claude Code 中输入/add-error-tracking确认已加载。

详细介绍

添加错误追踪

将 Temps 错误追踪(兼容 Sentry)集成到应用中。Temps DSN 可直接替换 Sentry DSN——使用适用于用户平台的官方 Sentry SDK,并通过环境变量将其指向 Temps DSN。

优先使用 Sentry 针对各框架提供的官方技能(如有)

Temps 与 Sentry 在线路协议上兼容,因此 Sentry 为其 SDK 发布的所有技能都可与 Temps DSN 配合使用。如果用户的 CLI 已安装以下技能之一,请引导他们使用该技能,只替换 DSN:

用户的平台Sentry 技能来源
Next.js/sentry-nextjs-sdkgetsentry/sentry-for-ai
React(Vite、Remix 等)/sentry-react-sdkgetsentry/sentry-for-ai
原生浏览器 JS/sentry-browser-sdkgetsentry/sentry-for-ai
Node.js/sentry-node-sdkgetsentry/sentry-for-ai
React Native/sentry-react-native-sdkgetsentry/sentry-for-ai
通用(语言无关)/sentry-sdk-setupgetsentry/sentry-for-ai

对于 Sentry 没有专用技能的平台(Vue、Svelte、Angular、Python、Go、Rust、Ruby、Java、PHP、.NET、Flutter 等),请直接按照本文件中的设置说明操作。

务必通过环境变量设置 DSN,切勿将其硬编码。 用户应将环境变量指向自己的 Temps DSN,而不是 Sentry DSN。

检测平台

根据代码库推断平台:

  • package.json 中包含 "next" → Next.js → @sentry/nextjs
  • package.json 中包含 "react",且使用 Vite/Remix/CRA → React → @sentry/react
  • package.json 中包含 "vue" 或 "nuxt" → Vue → @sentry/vue
  • package.json 中包含 "svelte" 或 "@sveltejs/kit" → Svelte → @sentry/sveltekit
  • package.json 中包含 "@angular/core" → Angular → @sentry/angular
  • package.json 中包含 "express"、"fastify"、"@nestjs/core" → Node.js → @sentry/node
  • package.json 中包含 "react-native" 或 "expo" → React Native → @sentry/react-native
  • requirements.txt/pyproject.toml 中包含 Flask、Django、FastAPI → Python → sentry-sdk
  • go.mod → Go → github.com/getsentry/sentry-go
  • Cargo.toml → Rust → sentry
  • Gemfile 中包含 rails → Ruby → sentry-ruby + sentry-rails
  • pom.xml/build.gradle 中包含 Spring → Java → sentry-spring-boot-starter-jakarta
  • composer.json 中包含 laravel/framework 或 symfony/* → PHP → sentry/sentry
  • .csproj 中包含 Microsoft.AspNetCore.* → .NET → Sentry.AspNetCore
  • pubspec.yaml 中包含 flutter → Flutter → sentry_flutter

获取 DSN

用户的 Temps 项目在 错误追踪 → DSN 与设置 中提供 DSN。格式如下:

https://<public_key>@<temps-host>/<project_id>

如果用户尚未提供 DSN,请告知他们:

  1. 在 Temps 控制面板中打开项目
  2. 前往 错误追踪 → DSN 与设置
  3. 复制目标环境对应的 DSN

务必将 DSN 存储在环境变量中。具体变量名取决于平台(浏览器打包工具通常要求使用特定前缀,才能将变量暴露给客户端):

平台环境变量名
Next.jsNEXT_PUBLIC_SENTRY_DSN
Vite / React / VueVITE_SENTRY_DSN
SvelteKitPUBLIC_SENTRY_DSN
AngularSENTRY_DSN(通过 environment.ts 注入)
其他所有平台(Node、Python、Go、Rust、Ruby、Java、PHP、.NET、Flutter)SENTRY_DSN
# .env
SENTRY_DSN=https://<public_key>@<temps-host>/<project_id>

浏览器 SDK:也要传入 tunnel

对于所有浏览器平台(Next.js 客户端配置、React、Vue、Svelte、原生 JS——不包括服务端 SDK,也不包括 React Native/Flutter),还要在同一次 Sentry.init 调用中传入 tunnel:

Sentry.init({
  dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
  tunnel: process.env.NEXT_PUBLIC_SENTRY_TUNNEL,
});

原因:如果不设置 tunnel,SDK 会直接向 DSN 的主机(Temps 控制台)发送 POST 请求。这是来自应用自身域名的第三方跨源请求——广告拦截器通常会拦截此类请求,而且每个事件都要进行一次 CORS 预检。将 tunnel 设置为同源路径后,浏览器会改为向应用自身的域名发送请求;Temps 的代理会将 /api/_temps 下的所有请求转发到控制台,不受请求来自哪个项目域名的影响,因此在自定义域名和预览 URL 上都无需修改即可使用。

该值是固定路径,并非密钥——Temps 会自动将其作为环境变量注入,并与 DSN 一同注入,使用相同的打包工具专属公开前缀(因此,如果 DSN 会进入客户端包,tunnel 路径也会):

平台DSN 环境变量Tunnel 环境变量
Next.jsNEXT_PUBLIC_SENTRY_DSNNEXT_PUBLIC_SENTRY_TUNNEL
Vite / React / VueVITE_SENTRY_DSNVITE_SENTRY_TUNNEL
SvelteKitPUBLIC_SENTRY_DSNPUBLIC_SENTRY_TUNNEL
AngularSENTRY_DSN(通过 environment.ts)(无——没有公开前缀约定;跳过 tunnel)

如果部署在 Temps 之外(或由于其他原因未设置 tunnel 变量),有两种选择。省略 tunnel——SDK 会回退为直接向 DSN 主机发送请求,仍然可以正常工作,只是会产生跨源请求。或者,将 tunnel 指向 Temps 实例的绝对 tunnel URL,例如 tunnel: "https://your-temps-instance.example.com/api/_temps/sentry/envelope": 该端点会根据 SDK 嵌入事件信封中的 DSN 来解析项目,因此无需通过 Temps 提供应用服务。这样,即使应用不由 Temps 托管,tunnel 仍能抵御广告拦截器,但代价是会产生同源方案可以避免的跨源请求。

除非确实需要,否则浏览器项目应省略 Sentry.replayIntegration() 和 tracesSampleRate——Temps 目前尚未接收 Sentry 会话回放或性能事务数据,因此这些流量会被上传(通过 tunnel,消耗访客的带宽),随后在服务端丢弃。对于这些功能,请改用 Temps 自己的会话回放和分析 SDK(参见 add-session-recording 和 add-react-analytics 技能)。

平台配置

以下每个代码片段都会从环境变量读取 DSN——不要将其硬编码。

Next.js
npx @sentry/wizard@latest -i nextjs

或手动配置:

npm install @sentry/nextjs
// sentry.client.config.ts (or instrumentation-client.ts on newer @sentry/nextjs)
import * as Sentry from '@sentry/nextjs';

Sentry.init({
  dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
  tunnel: process.env.NEXT_PUBLIC_SENTRY_TUNNEL,
});

在 sentry.server.config.ts 和 sentry.edge.config.ts 中设置相同的 dsn(不设置 tunnel,也不启用回放)——这些配置在服务端运行,会直接向控制台发送请求。

不要在 withSentryConfig 中设置 tunnelRoute——这是另一种机制(通过 Next.js 服务端路由转发),其文档明确指出它不适用于自托管 Sentry,而 Temps 使用的正是 Sentry DSN 兼容层。请使用上方展示的 tunnel 选项。

React(Vite、Remix、CRA)
npm install @sentry/react
// src/sentry.ts — import this first in main.tsx / root.tsx
import * as Sentry from '@sentry/react';

Sentry.init({
  dsn: import.meta.env.VITE_SENTRY_DSN,
  tunnel: import.meta.env.VITE_SENTRY_TUNNEL,
  environment: import.meta.env.MODE,
});

使用 <Sentry.ErrorBoundary> 包裹应用根节点,以捕获 React 渲染错误。

Vue(Vue 3 / Nuxt)
npm install @sentry/vue
// src/main.ts
import { createApp } from 'vue';
import * as Sentry from '@sentry/vue';
import App from './App.vue';

const app = createApp(App);

Sentry.init({
  app,
  dsn: import.meta.env.VITE_SENTRY_DSN,
  tunnel: import.meta.env.VITE_SENTRY_TUNNEL,
});

app.mount('#app');
Svelte / SvelteKit
npx @sentry/wizard@latest -i sveltekit
// src/hooks.client.ts
import * as Sentry from '@sentry/sveltekit';
import { PUBLIC_SENTRY_DSN, PUBLIC_SENTRY_TUNNEL } from '$env/static/public';

Sentry.init({
  dsn: PUBLIC_SENTRY_DSN,
  tunnel: PUBLIC_SENTRY_TUNNEL,
});

export const handleError = Sentry.handleErrorWithSentry();

在 src/hooks.server.ts 中使用 $env/dynamic/private 设置相同配置,以获取服务端 DSN。

Angular
npm install @sentry/angular
// src/main.ts
import * as Sentry from '@sentry/angular';
import { environment } from './environments/environment';

Sentry.init({
  dsn: environment.sentryDsn,
  tracesSampleRate: 1.0,
});

在构建时,将 environment.sentryDsn 的值设为 process.env.SENTRY_DSN。 Angular 不会注入公开前缀的 tunnel 变量(没有可供对照的打包工具约定)——此处跳过 tunnel;SDK 会直接向 DSN 主机发送请求。

原生 JavaScript(浏览器)
npm install @sentry/browser
import * as Sentry from '@sentry/browser';

Sentry.init({
  dsn: import.meta.env.VITE_SENTRY_DSN,
  tunnel: import.meta.env.VITE_SENTRY_TUNNEL,
});
Node.js
npm install @sentry/node
// Must be the first import in your entrypoint.
import * as Sentry from '@sentry/node';

Sentry.init({
  dsn: process.env.SENTRY_DSN,
  environment: process.env.NODE_ENV,
  tracesSampleRate: 1.0,
});

Express 配置:

import express from 'express';
import * as Sentry from '@sentry/node';

const app = express();
Sentry.setupExpressErrorHandler(app);
React Native
npx @sentry/wizard@latest -s -i reactNative
import * as Sentry from '@sentry/react-native';

Sentry.init({
  dsn: process.env.SENTRY_DSN,
  tracesSampleRate: 1.0,
  replaysSessionSampleRate: 0.1,
  replaysOnErrorSampleRate: 1.0,
});

export default Sentry.wrap(App);
Python
pip install sentry-sdk
import os
import sentry_sdk

sentry_sdk.init(
    dsn=os.environ["SENTRY_DSN"],
    environment=os.environ.get("ENV", "development"),
    traces_sample_rate=1.0,
    profiles_sample_rate=1.0,
)

框架集成:

# Flask
from sentry_sdk.integrations.flask import FlaskIntegration
sentry_sdk.init(dsn=os.environ["SENTRY_DSN"], integrations=[FlaskIntegration()])

# Django
from sentry_sdk.integrations.django import DjangoIntegration
sentry_sdk.init(dsn=os.environ["SENTRY_DSN"], integrations=[DjangoIntegration()])

# FastAPI
from sentry_sdk.integrations.starlette import StarletteIntegration
from sentry_sdk.integrations.fastapi import FastApiIntegration
sentry_sdk.init(
    dsn=os.environ["SENTRY_DSN"],
    integrations=[StarletteIntegration(), FastApiIntegration()],
)
Go
go get github.com/getsentry/sentry-go
package main

import (
    "log"
    "os"
    "time"

    "github.com/getsentry/sentry-go"
)

func main() {
    err := sentry.Init(sentry.ClientOptions{
        Dsn:              os.Getenv("SENTRY_DSN"),
        TracesSampleRate: 1.0,
        Environment:      os.Getenv("ENV"),
    })
    if err != nil {
        log.Fatalf("sentry.Init: %s", err)
    }
    defer sentry.Flush(2 * time.Second)
}
Rust
cargo add sentry sentry-tracing
use std::env;

fn main() {
    let _guard = sentry::init((
        env::var("SENTRY_DSN").expect("SENTRY_DSN must be set"),
        sentry::ClientOptions {
            release: sentry::release_name!(),
            traces_sample_rate: 1.0,
            environment: env::var("ENV").ok().map(Into::into),
            ..Default::default()
        },
    ));

    // Your app entrypoint
}
Ruby(Rails)
bundle add sentry-ruby sentry-rails
# config/initializers/sentry.rb
require "sentry-ruby"
require "sentry-rails"

Sentry.init do |config|
  config.dsn = ENV["SENTRY_DSN"]
  config.environment = ENV.fetch("RAILS_ENV", "development")
  config.traces_sample_rate = 1.0
end
Java(Spring Boot)

<dependency>
  <groupId>io.sentry</groupId>
  <artifactId>sentry-spring-boot-starter-jakarta</artifactId>
  <version>7.14.0</version>
</dependency>
# application.properties — Spring reads ${SENTRY_DSN} from the environment
sentry.dsn=${SENTRY_DSN}
sentry.environment=${ENV:development}
sentry.traces-sample-rate=1.0
PHP
composer require sentry/sentry
<?php
\Sentry\init([
    'dsn' => $_ENV['SENTRY_DSN'],
    'environment' => $_ENV['APP_ENV'] ?? 'development',
    'traces_sample_rate' => 1.0,
]);

对于 Laravel,请使用 sentry/sentry-laravel,并通过 config/sentry.php 读取 env('SENTRY_DSN') 进行配置。

.NET(ASP.NET Core)
dotnet add package Sentry.AspNetCore
// Program.cs
builder.WebHost.UseSentry(options =>
{
    options.Dsn = Environment.GetEnvironmentVariable("SENTRY_DSN");
    options.Environment = builder.Environment.EnvironmentName;
    options.TracesSampleRate = 1.0;
});
Flutter
flutter pub add sentry_flutter
import 'package:flutter/widgets.dart';
import 'package:sentry_flutter/sentry_flutter.dart';

Future<void> main() async {
  await SentryFlutter.init(
    (options) {
      options.dsn = const String.fromEnvironment('SENTRY_DSN');
      options.tracesSampleRate = 1.0;
    },
    appRunner: () => runApp(const MyApp()),
  );
}

在构建时传入 DSN:flutter run --dart-define=SENTRY_DSN=$SENTRY_DSN。

捕获自定义错误

JavaScript / TypeScript
import * as Sentry from '@sentry/react'; // or /browser, /node, /nextjs, etc.

try {
  doRiskyThing();
} catch (err) {
  Sentry.captureException(err);
}

Sentry.captureMessage('Something notable happened', 'warning');
Python
try:
    do_risky_thing()
except Exception as exc:
    sentry_sdk.capture_exception(exc)

sentry_sdk.capture_message("Something notable happened", level="warning")
Go
sentry.CaptureException(err)
sentry.CaptureMessage("Something notable happened")
Rust
sentry::capture_error(&err);
sentry::capture_message("Something notable happened", sentry::Level::Warning);

Source maps(仅限 JS/TS)

在 CI 期间上传 source maps,这样 Temps 仪表板就能在堆栈跟踪中显示原始源代码。

npm install --save-dev @sentry/cli
sentry-cli sourcemaps inject ./dist
sentry-cli sourcemaps upload \
  --url-prefix '~/' \
  --release "$GIT_SHA" \
  ./dist

Temps 仪表板也支持通过界面中的 Error Tracking → Source Maps 上传 source maps。

验证

接入完成后:

  1. 在应用中主动抛出错误:
    • JS / TS:throw new Error('Temps error tracking test');
    • Python:raise Exception('Temps error tracking test')
    • Go:sentry.CaptureException(errors.New("Temps test"))
    • Rust:panic!("Temps test")(在由 Sentry 集成捕获的处理程序中)
  2. 运行应用,并触发会抛出错误的路径。
  3. 打开 Temps 仪表板中的 Error Tracking → Error Groups — 错误应在几秒内出现。
  4. 确认堆栈跟踪和环境信息均已填充。

常见问题

  • 没有显示任何内容:请确认已加载 DSN 环境变量,并且 SDK 在任何可能抛出错误的代码运行前已初始化。对于 Node,Sentry.init 必须是第一个导入项。
  • 堆栈跟踪已压缩:请上传 source maps(见上文)。
  • 浏览器应用未上报:请确保环境变量使用打包工具的公开前缀(NEXT_PUBLIC_、VITE_、PUBLIC_),以便它能进入客户端包。
  • 生产环境缺少事件:请确认部署环境已设置 DSN 环境变量 — 本地 .env 文件不会自动复制。
  • 隧道请求返回 403:隧道端点会检查请求的 Origin(或 Referer)是否与请求到达的域名匹配 — 这可以阻止脚本向他人的项目发送伪造事件,但也会拒绝任何会删除或重写 Origin 的请求代理或改写操作。请确认浏览器与应用之间没有任何环节移除该标头。
  • 隧道请求返回 404:隧道会通过 Temps 的路由表,从 Host 标头解析项目 — 这仅适用于实际部署在 Temps 上的域名。用于 Temps 未提供服务的域名上的 tunnel 环境变量(例如,使用其他环境的 URL 进行测试)没有可供解析的目标。

评论

支持 Markdown