laravel-debugging-prompts について
laravel-debugging-promptsは、AIを使ってLaravelアプリケーションをデバッグする開発者向けのプロンプト集です。エラー、スタックトレース、期待値と実際の結果、ログ、証拠、試した対処法を伝え、具体的な文脈を示す方法を紹介します。
主な機能
- 01エラー報告のテンプレート
- 02期待値と実際の結果の例
- 03ログと状態情報のガイド
- 04仮説と証拠の整理方法
- 05パフォーマンス問題のテンプレート
活用シーン
- 01スタックトレース付きでLaravelの例外を報告
- 02APIの結果が期待と異なる状況を説明
- 03キューログとジョブの状態を共有
- 04性能指標と試した対処法を記録
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ noartem/ skills --skill laravel-debugging-promptsインストール後、Claude Code で/laravel-debugging-promptsを入力して読み込まれたか確認します。
詳細
デバッグプロンプト
AI を使ったデバッグには、完全な情報が必要です。コンテキストが不足していると、具体的な問題の解決につながらない一般的な提案しか得られません。
エラーメッセージとスタックトレース
不完全
「決済コントローラーでエラーが発生します」
完全
「決済の処理時にエラーが発生します。
エラー:
Illuminate\Database\QueryException: SQLSTATE[23000]:
Integrity constraint violation: 1452 Cannot add or update a child row:
a foreign key constraint fails (`app`.`payments`, CONSTRAINT `payments_order_id_foreign`
FOREIGN KEY (`order_id`) REFERENCES `orders` (`id`) ON DELETE CASCADE)
スタックトレース:
#0 app/Services/PaymentService.php(45): Payment::create()
#1 app/Http/Controllers/PaymentController.php(28): PaymentService->process()
#2 vendor/laravel/framework/src/Illuminate/Routing/Controller.php(54)
コンテキスト:
- Laravel 11.x、MySQL 8.0
order_idがordersテーブルに存在しない場合に発生- 決済データ:
['order_id' => 999, 'amount' => 5000, 'status' => 'pending'] - データベースに注文 999 は存在しません」
効果がある理由: エラー、スタックトレース、コンテキスト、問題の原因となる具体的なデータがそろっています。
期待される動作と実際の動作
曖昧
「API が正しいデータを返しません」
具体的
「Product API が正しくないデータを返します。
期待される動作:
{
"data": {
"id": 1,
"name": "Widget",
"price": "29.99",
"category": {
"id": 5,
"name": "Tools"
}
}
}
実際の動作:
{
"data": {
"id": 1,
"name": "Widget",
"price": 2999,
"category": null
}
}
問題:
- 価格が書式設定されたドル表記("29.99")ではなく、セント単位(2999)になっています
- 商品に
category_id = 5があるにもかかわらず、カテゴリが null です
コード:
// ProductController@show
return new ProductResource($product);
データベースでは商品に category_id = 5 が設定されていますが、リレーションが読み込まれていません。」
効果がある理由: 期待される出力と実際の出力を正確に示し、具体的な問題を特定して、関連するコードを含めています。
ログエントリーと状態
不十分
「キューで何か問題が起きています」
十分
「キュー内のジョブが失敗します。
ログエントリー:
[2024-01-15 10:30:15] local.ERROR: Job failed: ProcessOrderJob
{"order_id":123,"exception":"Stripe\\Exception\\InvalidRequestException:
No such customer: cus_invalid","attempts":3}
[2024-01-15 10:30:15] local.INFO: Order state before job
{"id":123,"status":"pending","stripe_customer_id":"cus_invalid"}
ジョブのコード:
public function handle()
{
$customer = $this->stripe->customers->retrieve(
$this->order->stripe_customer_id
);
// ...
}
状態:
- 注文 123 の
stripe_customer_id = "cus_invalid" - Stripe に顧客が存在しません
- ジョブは 3 回再試行され、現在は failed_jobs テーブルにあります
- Laravel 11.x と Horizon を使用しています」
効果がある理由: ログ、状態情報、関連するコード、再試行に関するコンテキストが含まれています。
仮説と証拠
弱い
「キャッシュの問題だと思います」
強い
「Redis キャッシュが古くなっている疑いがあります。
仮説: 商品価格がキャッシュされており、更新時に無効化されていません。
証拠:
- データベースの商品価格を更新:
UPDATE products SET price = 3999 WHERE id = 1 - データベースの表示:
SELECT price FROM products WHERE id = 1→3999 - API が古い価格を返す:
GET /api/products/1→"price": "29.99" php artisan cache:clearの実行後、API が正しい価格を返す:"price": "39.99"
キャッシュのコード:
public function show(Product $product)
{
$cached = Cache::remember("product.{$product->id}", 3600, function () use ($product) {
return new ProductResource($product);
});
return $cached;
}
問題: 商品の更新時にキャッシュキーが無効化されません。ProductObserver でキャッシュを無効化するか、show メソッドからキャッシュを削除する必要があります。」
効果がある理由: 明確な仮説、具体的な証拠、関連するコード、提案する解決策が含まれています。
試した解決策
役に立たない
「いくつか試しましたが、何も解決しませんでした」
役に立つ
「試した解決策と結果:
試行 1: Eager Loading を追加
$products = Product::with('category')->get();
結果: N+1 クエリが引き続き発生します。Debugbar には 101 個のクエリ(商品に 1 個、カテゴリに 100 個)と表示されます。
試行 2: 取得後に load() を使用
$products = Product::all();
$products->load('category');
結果: 同じ問題が続き、クエリは依然として 101 個です。
試行 3: リレーションの定義を確認
// In Product model
public function category()
{
return $this->belongsTo(Category::class);
}
結果: リレーションは正しいようです。外部キー category_id は products テーブルに存在します。
現在の状態: Eager Loading の構文は正しいようですが、機能していません。Laravel 11.x を使用しています。何を見落としているのでしょうか?」
効果がある理由: 試したこと、実際に使用したコード、確認した結果を示すことで、すでに試した解決策を提案されずに済みます。
デバッグ用テンプレート
テンプレート:エラーレポート
**Error:** [Full error message]
**Stack trace:** [Complete stack trace]
**File/Line:** [Where error occurs]
**Context:** [Laravel version, packages, environment]
**Data:** [Input data causing error]
**Expected:** [What should happen]
テンプレート:予期しない動作
**Expected:** [Describe expected behavior with example]
**Actual:** [Describe actual behavior with example]
**Code:** [Relevant code snippet]
**State:** [Database state, variable values]
**Environment:** [Laravel version, Sail/host, packages]
テンプレート:パフォーマンスの問題
**Problem:** [Describe slow operation]
**Metrics:** [Response time, query count, memory usage]
**Query log:** [Slow queries from Debugbar/Telescope]
**Code:** [Code causing performance issue]
**Dataset size:** [Number of records involved]
**Attempted:** [Optimizations already tried]
クイックリファレンス
AI を使って効果的にデバッグするには:
- エラーの全容を示す - メッセージ全文、スタックトレース、ファイルと行番号
- 両方を示す - 期待される動作と実際の動作
- ログを含める - エラーログ、情報ログ、状態のダンプ
- 証拠を共有する - データベースクエリ、API レスポンス、変数のダンプ
- 試したことを記録する - 試した内容、実際のコード、結果
- コンテキストを伝える - Laravel のバージョン、環境、パッケージ
情報が多いほど、解決が早くなります。デバッグでは、情報を詳しく伝えましょう。