エラーフォーマット
すべてのエラーレスポンスは一貫した構造に従います:
{
"data": null,
"errors": [
{
"message": "Missing required field: name",
"layer": "product"
}
]
}
エラー配列の読み方
errors 配列はルートコーズからトップレベルの呼び出し元の順に並びます:
errors[0] — ルートコーズ(デバッグに最も有用)
errors[n] — エラーを表面化させたトップレベルの呼び出し元
ほとんどの場合、errors[0].message を確認するだけで実用的なエラー説明が得られます。
HTTP ステータスコード
| コード | 意味 | 説明 |
|---|
| 200 | 成功 | リクエストが正常に処理された |
| 400 | 不正なリクエスト | パラメータ無効またはリクエストボディの形式が不正 |
| 401 | 未認証 | 認証情報が不足または無効 |
| 403 | 禁止 | 有効な認証情報だが権限不足 |
| 404 | 見つからない | リクエストされたリソースが存在しない |
| 409 | 競合 | 冪等リクエストが既に処理中 |
| 429 | レート制限 | 短期間にリクエストが多すぎる |
| 500 | サーバーエラー | 内部サーバーエラー |
| 501 | 未実装 | リクエストされた機能がまだ利用不可 |
| 502 | ゲートウェイエラー | アップストリームサービスのエラー |
エラーレイヤー
各エラーには、システム内のどこでエラーが発生したかを示す layer フィールドが含まれます:
| レイヤー | 説明 | 一般的な原因 |
|---|
gateway | リクエストルーティング | 無効な URL、サーバー利用不可 |
user | 認証 / 認可 | トークン期限切れ、ロール不正 |
store | ストア操作 | ストアが存在しない、権限不足 |
product | プロダクト操作 | 無効な価格、必須フィールド不足 |
order | オーダー操作 | 無効なプロダクトバージョン、チェックアウトエラー |
graphql | GraphQL クエリ | 無効なクエリ、未知のフィールド |
コードでのエラー処理
TypeScript SDK
import { WaffoPancake, WaffoPancakeError } from "@waffo/pancake-ts";
const client = new WaffoPancake({
merchantId: process.env.WAFFO_MERCHANT_ID!,
privateKey: process.env.WAFFO_PRIVATE_KEY!,
});
try {
const { store } = await client.stores.create({ name: "My Store" });
} catch (err) {
if (err instanceof WaffoPancakeError) {
const rootCause = err.errors[0];
console.error(`Error [${rootCause.layer}]: ${rootCause.message}`);
// err.status には HTTP ステータスコードが含まれます
}
}
リトライ戦略
以下のステータスコードには指数バックオフでリトライ:
- 429 — レート制限(
Retry-After ヘッダーがあれば尊重)
- 500 — 内部サーバーエラー
- 502 — ゲートウェイエラー
async function retryRequest(fn, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await fn();
} catch (error) {
const status = error.status;
if (![429, 500, 502].includes(status) || attempt === maxRetries - 1) {
throw error;
}
const delay = Math.pow(2, attempt) * 1000;
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}
400、401、403、404 エラーはリトライしないでください。これらはリクエスト自体に修正が必要です。
冪等性による安全なリトライ
X-Idempotency-Key ヘッダーを使用して、重複を作成せずに書き込み操作を安全にリトライ:
curl -X POST https://waffo-pancake-auth-service.vercel.app/v1/actions/checkout/create-session \
-H "Content-Type: application/json" \
-H "X-Store-Slug: your-store-slug" \
-H "X-Environment: test" \
-H "X-Idempotency-Key: order-abc-123" \
-d '{"productId": "...", "productType": "onetime", "currency": "USD"}'
- 冪等キーは 24 時間 キャッシュされます
- 同じキーを送信するとキャッシュされたレスポンスが返されます
- 元のリクエストがまだ処理中の場合、
409 Conflict が返されます