add-error-tracking について
add-error-tracking は、アプリに Temps のエラートラッキングを導入するためのセットアップスキルです。複数の言語やフレームワークでエラー報告を設定する開発者向けに、Sentry 互換 DSN と公式 Sentry SDK、ブラウザー用トンネルの設定を案内します。
主な機能
- 01コードベースからプラットフォームを判定
- 02公式 Sentry SDK の設定
- 03環境変数による DSN 設定
- 04ブラウザー SDK のトンネル設定
- 05各種プラットフォームの設定例
- 06カスタム例外の捕捉
活用シーン
- 01Next.js アプリに Temps のエラートラッキングを導入
- 02Node.js や Python サービスでエラーを報告
- 03ブラウザーアプリに同一オリジンのイベントトンネルを設定
- 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-sdk | getsentry/sentry-for-ai |
| React(Vite、Remixなど) | /sentry-react-sdk | getsentry/sentry-for-ai |
| VanillaブラウザーJS | /sentry-browser-sdk | getsentry/sentry-for-ai |
| Node.js | /sentry-node-sdk | getsentry/sentry-for-ai |
| React Native | /sentry-react-native-sdk | getsentry/sentry-for-ai |
| 汎用(言語に依存しない) | /sentry-sdk-setup | getsentry/sentry-for-ai |
Sentryに専用スキルがないプラットフォーム(Vue、Svelte、Angular、Python、Go、Rust、Ruby、Java、PHP、.NET、Flutterなど)では、このファイルの設定手順に従ってください。
DSNは必ず環境変数から設定してください。ハードコードしてはいけません。 ユーザーはSentryのDSNではなく、TempsのDSNを環境変数に指定します。
プラットフォームを特定する
コードベースからプラットフォームを推測します。
"next"を含むpackage.json→ Next.js →@sentry/nextjs"react"とVite/Remix/CRAを含むpackage.json→ React →@sentry/react"vue"または"nuxt"を含むpackage.json→ Vue →@sentry/vue"svelte"または"@sveltejs/kit"を含むpackage.json→ Svelte →@sentry/sveltekit"@angular/core"を含むpackage.json→ Angular →@sentry/angular"express"、"fastify"、"@nestjs/core"を含むpackage.json→ Node.js →@sentry/node"react-native"または"expo"を含むpackage.json→ React Native →@sentry/react-native- Flask、Django、FastAPIを含む
requirements.txt/pyproject.toml→ Python →sentry-sdk go.mod→ Go →github.com/getsentry/sentry-goCargo.toml→ Rust →sentryrailsを含むGemfile→ Ruby →sentry-ruby+sentry-rails- Springを含む
pom.xml/build.gradle→ Java →sentry-spring-boot-starter-jakarta laravel/frameworkまたはsymfony/*を含むcomposer.json→ PHP →sentry/sentryMicrosoft.AspNetCore.*を含む.csproj→ .NET →Sentry.AspNetCoreflutterを含むpubspec.yaml→ Flutter →sentry_flutter
DSNを取得する
ユーザーのTempsプロジェクトでは、エラートラッキング → DSNとセットアップにDSNが表示されます。次のような形式です。
https://<public_key>@<temps-host>/<project_id>
ユーザーがDSNを提供していない場合は、次の手順を案内してください。
- Tempsダッシュボードでプロジェクトを開く
- エラートラッキング → DSNとセットアップに移動する
- 対象の環境のDSNをコピーする
DSNは必ず環境変数に保存してください。正確な変数名はプラットフォームによって異なります(ブラウザーバンドラーでは、クライアントに変数を公開するためのプレフィックスが必要なことがよくあります)。
| プラットフォーム | 環境変数名 |
|---|---|
| Next.js | NEXT_PUBLIC_SENTRY_DSN |
| Vite/React/Vue | VITE_SENTRY_DSN |
| SvelteKit | PUBLIC_SENTRY_DSN |
| Angular | SENTRY_DSN(environment.ts経由で注入) |
| その他すべて(Node、Python、Go、Rust、Ruby、Java、PHP、.NET、Flutter) | SENTRY_DSN |
# .env
SENTRY_DSN=https://<public_key>@<temps-host>/<project_id>
Browser SDK:tunnel も渡します
すべてのブラウザープラットフォーム(Next.js のクライアント設定、React、Vue、Svelte、vanilla 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 に同一オリジンのパスを設定すると、ブラウザーは代わりにアプリ自身のドメインに POST します。Temps のプロキシは、どのプロジェクトドメインから届いたかにかかわらず、/api/_temps 配下のすべてのリクエストをコンソールに転送するため、カスタムドメインやプレビュー URL でも変更なしで動作します。
値は固定パスであり、秘密情報ではありません。Temps は DSN とともに、同じバンドラー固有の公開プレフィックスを使って、環境変数として自動的に注入します(DSN がクライアントバンドルに含まれる場合、トンネルパスも含まれます)。
| プラットフォーム | DSN 環境変数 | Tunnel 環境変数 |
|---|---|---|
| Next.js | NEXT_PUBLIC_SENTRY_DSN | NEXT_PUBLIC_SENTRY_TUNNEL |
| Vite / React / Vue | VITE_SENTRY_DSN | VITE_SENTRY_TUNNEL |
| SvelteKit | PUBLIC_SENTRY_DSN | PUBLIC_SENTRY_TUNNEL |
| Angular | SENTRY_DSN(environment.ts 経由) | (なし — 公開プレフィックスの規約がないため、tunnel は省略します) |
Temps の外部にデプロイする場合(または何らかの理由でトンネル変数が設定されていない場合)は、2 つの方法があります。tunnel を省略すると、SDK は DSN のホストへの直接 POST にフォールバックします。クロスオリジンにはなりますが、引き続き動作します。あるいは、tunnel に Temps インスタンスの絶対トンネル URL を指定します。例:tunnel: "https://your-temps-instance.example.com/api/_temps/sentry/envelope"。エンドポイントは SDK がエンベロープに埋め込む DSN からプロジェクトを特定するため、アプリを Temps で配信する必要はありません。この方法なら、Temps がホストしていないアプリでもトンネルによる広告ブロッカー対策を維持できますが、同一オリジンの方法では回避できるクロスオリジンリクエストが発生します。
ブラウザープロジェクトでは、特に必要でない限り、Sentry.replayIntegration() と tracesSampleRate は省略してください。Temps は Sentry のセッションリプレイやパフォーマンストランザクションをまだ取り込めないため、そうしたトラフィックは(トンネル経由で訪問者の帯域幅を使って)アップロードされた後、サーバー側で破棄されます。代わりに、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,
});
dsn(tunnel とリプレイは含めません)を sentry.server.config.ts と sentry.edge.config.ts にも設定してください。これらはサーバーサイドで実行され、コンソールに直接 POST します。
withSentryConfig で tunnelRoute を設定しないでください。これは別の仕組み(Next.js のサーバールート経由で転送)であり、そのドキュメントにも、Temps の DSN 互換レイヤーが該当するセルフホストの Sentry では動作しないと記載されています。代わりに、上記の 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,
});
React のレンダリングエラーを捕捉するには、アプリのルートを <Sentry.ErrorBoundary> で囲みます。
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();
サーバー側の DSN には $env/dynamic/private を使用して、src/hooks.server.ts にも同じ設定を追加します。
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,
});
ビルド時に process.env.SENTRY_DSN から environment.sentryDsn を設定します。Angular には公開プレフィックスのトンネル変数は注入されません(対応するバンドラー規約がないため)。ここでは tunnel を省略し、SDK が DSN のホストに直接 POST するようにします。
Vanilla 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 を使用し、env('SENTRY_DSN') を読み込むように config/sentry.php で設定します。
.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);
ソースマップ(JS/TS のみ)
Temps のダッシュボードでスタックトレースに元のソースを表示できるよう、CI 中にソースマップをアップロードします。
npm install --save-dev @sentry/cli
sentry-cli sourcemaps inject ./dist
sentry-cli sourcemaps upload \
--url-prefix '~/' \
--release "$GIT_SHA" \
./dist
Temps のダッシュボードでは、UI の エラートラッキング → ソースマップ からもソースマップをアップロードできます。
検証
設定後、次の手順を実行します。
- アプリから意図的にエラーを発生させます。
- 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 統合によってキャッチされるハンドラー内で実行)
- JS / TS:
- アプリを実行し、エラーを発生させるパスを実行します。
- Temps のダッシュボードで エラートラッキング → エラーグループ を開きます。数秒以内にエラーが表示されるはずです。
- スタックトレースと環境が設定されていることを確認します。
よくある問題
- 何も表示されない:DSN の環境変数が読み込まれていること、およびエラーが発生する可能性のあるコードより前に SDK が初期化されていることを確認します。Node では、
Sentry.initを最初のインポートにする必要があります。 - スタックトレースが圧縮されている:ソースマップをアップロードします(上記を参照)。
- ブラウザーアプリから報告されない:環境変数にバンドラーの公開用プレフィックス(
NEXT_PUBLIC_、VITE_、PUBLIC_)を付けて、クライアントバンドルに含まれるようにします。 - 本番環境でイベントが届かない:デプロイ環境に DSN の環境変数が設定されていることを確認します。ローカルの
.envファイルは自動的にコピーされません。 - トンネル経由のリクエストが 403 になる:トンネルエンドポイントは、リクエストの
Origin(またはReferer)が到達先のドメインと一致するかを確認します。これにより、別のユーザーのプロジェクトに偽装したイベントを送るスクリプトは拒否されますが、Originを削除または書き換えるプロキシ処理などによってリクエストが変更された場合も拒否されます。ブラウザーとアプリの間で、このヘッダーを削除するものがないことを確認します。 - トンネル経由のリクエストが 404 になる:トンネルは Temps のルーティングテーブルを使い、
Hostヘッダーからプロジェクトを特定します。これは、Temps に実際にデプロイされているドメインでのみ機能します。Temps が提供していないドメインで使用されるtunnel環境変数(たとえば、別の環境の URL でテストする場合)では、解決先がありません。