👾
【F#】Google Drive API のエラーハンドリング
前提
応答: System.Net.Http.HttpResponseMessage [↗]
成功か判定する
200-299
copy, create, export, generateIds, get, list, update, watch.
応答.IsSuccessStatusCode
204
応答.StatusCode = System.Net.HttpStatusCode.NoContent
[3]
処理が可能なエラーか判定する[4]
401 (初回)無効なアクセストークン。
応答.StatusCode = System.Net.HttpStatusCode.Unauthorized
[5], 500, 502, 503, 504[6]
429時間を置けば解決するかもしれないエラー。
let retryCodes =
Set [
System.Net.HttpStatusCode.TooManyRequests // 429
System.Net.HttpStatusCode.InternalServerError // 500
System.Net.HttpStatusCode.BadGateway // 502
System.Net.HttpStatusCode.ServiceUnavailable // 503
System.Net.HttpStatusCode.GatewayTimeout // 504
]
retryCodes |> Set.contains 応答.StatusCode
エラーハンドリングの実装例
[7]
指数関数的バックオフlet randomNumberGenerator = System.Random()
let Backoff (retryCount: int) =
let currentWaitMilliseconds =
min
<| (2. ** float retryCount) * 1000.
<| 32000.
let jitterMilliseconds = int currentWaitMilliseconds + randomNumberGenerator.Next(1, 1001)
System.Threading.Tasks.Task.Delay(jitterMilliseconds).Wait()
エラーハンドリングの擬似コード
let rec TryXX (retryCount: int) =
match リクエスト処理() with
| r when r.IsSuccessStatusCode -> 成功時の処理
| r when r.StatusCode = System.Net.HttpStatusCode.Unauthorized ->
match retryCount with
| 0 -> refresh()
| _ -> failwith "アクセストークン更新処理のエラー"
| r when retryCodes |> Set.contains r.StatusCode -> backoff retryCount
| _ -> failwith "未定義なエラー"
and refresh () =
アクセストークンの更新処理
TryXX 1
and backoff (retryCount: int) =
match retryCount with
| 試行回数の上限 -> failwith "試行回数の上限"
| _ -> Backoff retryCount
TryXX (retryCount + 1)
// ...
TryXX 0
end
-
https://developers.google.com/drive/api/v3/reference/files/delete#response ↩︎
-
https://developers.google.com/drive/api/v3/reference/files/emptyTrash#response ↩︎
-
https://developers.google.com/drive/api/v3/handle-errors#resolve_a_401_error_invalid_credentials ↩︎
-
https://developers.google.com/drive/api/v3/handle-errors#resolve_a_429_error_too_many_requests ↩︎
-
https://developers.google.com/drive/api/v3/handle-errors#resolve_a_500_error_backend_error ↩︎
Discussion