やりたい事
Faradayを使い、APIからのレスポンスがステータス200 OKでも、レスポンスボディの内容(例: {'status': 'processing'})を条件にリクエストをリトライさせたい。
発生した問題
以下のように、retry_ifブロックでボディの内容をチェックするロジックを記述したが、ステータス200のレスポンスを受け取った時点で、retry_ifが評価されずに処理が終了してしまう。
# 期待通りに動かないコード
builder.request :retry, {
max: 5,
retry_if: ->(env, _exception) do
if env.status == 200
JSON.parse(env.body)['status'] == 'processing'
end
end
}
原因
retry_statusesオプションのチェックが先に実行され、ここでリトライ対象外のステータス(デフォルトでは200)だと判断されると、retry_ifブロックは評価されずに処理が終了してしまうことが原因だった。
同じ疑問を持っている方もいました。
https://github.com/lostisland/faraday-retry/issues/31
※最新は挙動が違うかも?
https://github.com/lostisland/faraday-retry/blob/main/lib/faraday/retry/middleware.rb
修正後のコード
builder.request :retry, {
max: 5,
# 200をリトライ検討対象に加える
retry_statuses: [200],
# レスポンスボディから、詳細な条件を評価する
retry_if: ->(env, _exception) do
if env.status == 200
JSON.parse(env.body)['status'] == 'processing'
end
end
}
あくまで参考程度に、各リトライ条件に応じて設定してください!