sentry-javascript-bugs について
Sentry のフロントエンドコード向け JavaScript バグレビューのスキルです。実際の本番障害に見られたパターンをもとに、指定コードまたは現在のブランチ差分を確認します。関連するデータフローを追い、具体的な発生条件がある中・高確度の問題だけを報告します。
主な機能
- 01null アクセスと API レスポンス処理の検査
- 02ダッシュボードとトレースビューのデータ確認
- 03React ライフサイクルと AI データ解析の検査
- 04配列境界とロジックの検証
- 05発生条件と具体的な修正コードの提示
活用シーン
- 01フロントエンド差分の null アクセスリスク確認
- 02チャートやトレースの想定外データ処理の検査
- 03非同期処理や React ライフサイクル問題の調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ getsentry/ sentry --skill sentry-javascript-bugsインストール後、Claude Code で/sentry-javascript-bugsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
README.mdreferences/ai-insights-parsing.mdapi-response-handling.mddashboard-widget-errors.mdnull-reference-errors.mdrange-and-bounds-errors.mdreact-lifecycle-errors.mdtrace-view-errors.md詳細
Sentry JavaScript フロントエンドバグパターンレビュー
実際の本番環境で最も多くのエラーを引き起こしているパターンをチェックすることで、Sentry フロントエンドコードのバグを見つけます。
このスキルは、428 件の実際の本番環境の問題(解決済み 201 件、無視 130 件、未解決 97 件)から得られたパターンをエンコードしたもので、93,000 人以上の影響を受けたユーザーにわたり 524,000 件を超えるエラーイベントを生成しています。これらは理論上のリスクではありません。最も頻繁に出荷される実際のバグであり、解決済みの問題から得られた既知の修正方法があります。
スコープ
ユーザー、Warden、または現在のブランチの差分によって提供されたコードをレビューします。ユーザーが対象を指定しない場合は、現在のブランチの差分をレビューします。変更されたハンクまたはファイルから開始し、挙動を確認するために必要な範囲でのみ外側へ読み進めます。
- 変更されたコードを以下のパターンチェックに照らして分析します。
- 必要に応じて、
ReadとGrepを使用して最初の差分を超えてデータフローを追跡します。コンポーネントの props、フックの戻り値、API レスポンスの形状、状態遷移を、挙動が確認できるまで追跡します。 - HIGH および MEDIUM 信頼度の検出事項のみを報告します。
| 信頼度 | 基準 | アクション |
|---|---|---|
| HIGH | コードパスを追跡し、パターンが既知のバグクラスと一致することを確認した | 修正方法とともに報告 |
| MEDIUM | パターンは存在するが、コンテキストがそれを緩和する可能性がある | 要検証として報告 |
| LOW | 理論上または他の場所で緩和されている | 報告しない |
ステップ 1: コードを分類する
レビュー対象を判断し、関連するリファレンスを読み込みます。
| コードの種類 | 読み込むリファレンス |
|---|---|
| Null/undefined のプロパティアクセス、オプショナルチェーン、オブジェクトの分割代入 | references/null-reference-errors.md |
| ダッシュボードウィジェット、チャートの可視化、ウィジェット URL の生成 | references/dashboard-widget-errors.md |
| トレースビュー、スパンの詳細、トレースツリーのレンダリング | references/trace-view-errors.md |
| API 呼び出し、レスポンスの処理、エラー状態、fetch ラッパー | references/api-response-handling.md |
| React フック、コンテキストプロバイダー、レンダリングループ、コンポーネントのライフサイクル | references/react-lifecycle-errors.md |
| AI Insights、LLM プロンプトの解析、gen_ai スパンデータ | references/ai-insights-parsing.md |
| 配列操作、日付/時刻の値、数値のフォーマット | references/range-and-bounds-errors.md |
コードが複数のカテゴリにまたがる場合は、関連するすべてのリファレンスを読み込みます。
ステップ 2: 主要なバグパターンをチェックする
これらは、実際の本番環境データから得られた頻度と影響の組み合わせ順に並べられています。
チェック 1: Null/Undefined のプロパティアクセス -- 158 件の問題、46,337 件のイベント
コードが、null または undefined の可能性がある値のプロパティにアクセスしています。これは Sentry フロントエンドで最も一般的な単一のバグパターンです。
危険信号:
- null チェックなしで
.id、.slug、.name、.type、.match、.length、.charCodeAtにアクセスしている - API レスポンスのデータに対して
object?.propertyではなくobject.propertyを使用している - null 検証なしで API レスポンスのデータをユーティリティ関数に直接渡している
- 要素が存在するか確認せずに
querySelectorまたはuseRefから DOM 要素のプロパティにアクセスしている - ローディング状態中に null を返す可能性があるフック/ストアからのオブジェクトを分割代入している
- アンマウントされた要素に対して
.dispatchEvent()を呼び出している
安全なパターン:
- オプショナルチェーン:
obj?.property?.nested - デフォルト値:
const value = obj?.field ?? defaultValue - 関数呼び出し前の null ガード:
if (data) { parser.parse(data); } - ユーティリティ関数における null/undefined パラメータの早期リターン
チェック 2: ダッシュボードウィジェットの入力検証 -- 6 件の問題、90,482 イベント
ウィジェットの可視化コンポーネントは、予期しない形式のデータを受け取ると例外をスローします。
危険な兆候:
- データにプロット可能な値が含まれているかを確認せずにチャートコンポーネントをレンダリングしている
- 複数のクエリをサポートしていないウィジェット種別に対して
getWidgetExploreUrl()を呼び出している - undefined の
field値をparseFunction()などのフィールドパーサーに渡している - ウィジェットのデータフェッチャーで空の API レスポンスを処理していない
安全なパターン:
- レンダリング前にデータの形状を検証する:
if (!hasPlottableValues(data)) return <EmptyState /> - 探索 URL を生成する前にウィジェットのクエリ数を確認する
- フィールドパーサーをガードする:
if (!field) return null
チェック 3: トレースビューのデータ整合性 -- 12 件の問題、328,482 イベント
トレースツリーレンダラーとトレース詳細ビューは、構造上の前提に違反するデータに遭遇します。
危険な兆候:
- 循環検出なしでトレースツリーを構築している(または循環を検出しても適切に処理していない)
- スパンデータから ID でプロジェクトを参照する際に、そのプロジェクトにアクセス可能かどうかを確認していない
traceSlugが空でないことを検証せずにトレースリンクを生成している- 重複排除なしでレンダリングパス内で
captureExceptionを使用している(レンダリングサイクルごとに発火する)
安全なパターン:
- 循環ノードを孤立ルートとして切り離すことで循環を断ち切る
- リンクを生成する前に traceSlug を検証する:
if (!traceSlug) return fallbackLink - ref を使ってエラーキャプチャを重複排除する:
if (!capturedRef.current) { captureException(...); capturedRef.current = true; } - スパンの詳細をレンダリングする前にプロジェクトへのアクセスを確認する
チェック 4: API レスポンスの形状に関する前提 -- 31 件の問題、24,019 イベント
フロントエンドコードは API レスポンスが特定の形状を持つと前提していますが、レスポンスが空であったり、undefined であったり、予期しないステータスコードであったりします。
危険な兆候:
- ボディが空の 200 レスポンスを処理していない(例:
GET /customers/{orgSlug}/がボディなしで 200 を返す) - サブスクリプションフローで 402(Payment Required)ステータスコードを処理していない
- ミューテーションエンドポイントで 409(Conflict)ステータスコードを処理していない
UndefinedResponseBodyErrorを予期しないものとして扱っている(これは API がパース可能なボディを返さなかったことを示します)- SelectAsync のオプションが常に正常に読み込まれると前提している
安全なパターン:
- パース前にレスポンスボディを確認する:
if (!response.body) return null - catch ブロックで特定の 4xx ステータスコードを処理する
- 失敗した API フェッチに対しては例外をスローする代わりにフォールバックの空状態を提供する
チェック 5: React ライフサイクル違反 -- 10 件の問題、2,595 イベント
コンポーネントが React のレンダリングルールに違反し、無限ループやクラッシュを引き起こします。
危険な兆候:
- 適切な依存配列なしで
useEffect内で無条件に state を設定している - 組織コンテキストが読み込まれる前にレンダリングされるコンポーネントで
useOrganization()を呼び出している - プロバイダーの境界外で
useContext()を使用している - 文字列や要素ではなくオブジェクトを React の children として渡している
- マウント時に即座に再レンダリングをトリガーするコンポーネント
安全なパターン:
useEffectには常に依存配列を指定する- コンテキストフックをガードする:
const org = useOrganization(); if (!org) return <Loading /> - 組織に依存するルートをプロバイダーの境界でラップする
- レンダリング前に要素の型を検証する:
if (typeof Component !== 'function') return null
チェック 6: AI インサイトのデータパース -- 2 件の問題、3,005 イベント
AI プロンプトメッセージと gen_ai スパンデータの JSON パースが、標準的でない形式で失敗します。
危険な兆候:
- try-catch なしで
ai.prompt.messagesスパン属性に対してJSON.parse()を呼び出している - すべての AI モデルレスポンスが有効な JSON を生成すると前提している
- マルチモーダル AI メッセージの「parts」形式を処理していない
安全なパターン:
- 外部データに対するすべての
JSON.parse呼び出しを try-catch でラップする - パース前に先頭の
[または{を確認する - パースが失敗した場合は生テキストのフォールバックレンダリングを提供する
チェック 7: 配列と境界の検証 -- 15 件の問題、3,120 件のイベント
有効な範囲を超える値を使用した配列操作と数値フォーマット。
危険な兆候:
result.push(...largeArray)の使用(配列が大きすぎるとクラッシュする)- クランプされていない値を
toLocaleString({maximumFractionDigits: n})に渡す - 検証されていないタイムスタンプから Date オブジェクトを構築する
- 深さ制限なしでの再帰的なコンポーネントレンダリング
安全なパターン:
- 大きくなる可能性のある配列には
concatまたは反復的な push を使用する - 数値フォーマットのパラメータをクランプする:
Math.min(100, Math.max(0, precision)) - 構築する前に日付を検証する:
if (isNaN(new Date(ts).getTime())) return fallback - 深くネストされた構造には、明示的なスタックを使用した反復的なレンダリングを使用する
チェック 8: ロジックの正確性 -- パターンベースではない
上記のすべての既知のパターンをチェックした後、変更されたコード自体について推論します:
- すべてのコードパスが正しい型(または JSX)を返しますか?
- 条件分岐のすべてのブランチが処理されていますか(特に switch における
else/ default ケースの欠落)? - 任意の prop や state の値(null、undefined、空の配列、空の文字列)が予期しない動作を引き起こす可能性がありますか?
- フックの依存関係配列は正しいですか? 依存関係の欠落は古いクロージャを引き起こし、余分な依存関係は無限ループを引き起こします。
- このコンポーネントが非同期操作の途中でアンマウントされた場合、クリーンアップは処理されていますか?
バグを引き起こす具体的な入力をトレースできる場合にのみ報告してください。理論上の懸念を報告しないでください。
チェックで潜在的な検出結果が得られなかった場合は、停止して検出結果ゼロを報告してください。レポートを埋めるために問題をでっち上げないでください。コードにこれらのパターンに一致するバグがない場合、空の結果が正しい出力です。
各コードの場所は、最も具体的に一致するパターンの下で一度だけ報告する必要があります。同じ行を複数のチェックで指摘しないでください。
ステップ 3: 検出結果の報告
各検出結果について、レビューハーネスが必要とする証拠を提供します:
- 正確な場所
- 重大度と信頼度
- 具体的なトリガーとなる入力または状態
- 根本原因と結果
- 利用可能な場合は、一致する本番環境での前例
- ハーネスがサポートする場合は、統合 diff 形式が望ましい具体的なコード修正
修正の提案には実際のコードを含める必要があります。修正としてコメントや docstring を提案しないでください。
独自の出力形式を規定しないでください -- レビューハーネスが応答構造を制御します。