mirror of
https://github.com/netfun2000/hipudding-teslamate.git
synced 2026-02-27 09:44:28 +08:00
feat: Respect Retry-After header on 429 response code (#3943)
* Respect 429 response code instructions * format * up * up --------- Co-authored-by: Julien <julien@citio.digital>
This commit is contained in:
@@ -55,6 +55,7 @@ config/*.env
|
||||
.eclipse/
|
||||
.elixir_ls/
|
||||
/.project
|
||||
.vscode/
|
||||
|
||||
# Mac files
|
||||
.DS_Store
|
||||
|
||||
@@ -113,6 +113,18 @@ defmodule TeslaApi.Vehicle do
|
||||
%Tesla.Env{status: 408, body: %{"error" => "vehicle unavailable:" <> _}} = env ->
|
||||
{:error, %Error{reason: :vehicle_unavailable, env: env}}
|
||||
|
||||
%Tesla.Env{status: 429, headers: headers} ->
|
||||
retry_after =
|
||||
case Enum.find(headers, fn {key, _value} -> key == "retry-after" end) do
|
||||
nil ->
|
||||
"300"
|
||||
|
||||
{"retry-after", value} ->
|
||||
value
|
||||
end
|
||||
|
||||
{:error, %Error{reason: :too_many_request, message: String.to_integer(retry_after)}}
|
||||
|
||||
%Tesla.Env{status: 504} = env ->
|
||||
{:error, %Error{reason: :timeout, env: env}}
|
||||
|
||||
|
||||
@@ -278,6 +278,10 @@ defmodule TeslaMate.Api do
|
||||
Logger.error("TeslaApi.Error / #{status} – #{inspect(body, pretty: true)}")
|
||||
{:error, reason}
|
||||
|
||||
{:error, %TeslaApi.Error{reason: :too_many_request, message: retry_after}} ->
|
||||
Logger.warning("TeslaApi.Error / :too_many_request #{retry_after}")
|
||||
{:error, :too_many_request, retry_after}
|
||||
|
||||
{:error, %TeslaApi.Error{reason: reason, message: msg}} ->
|
||||
if is_binary(msg) and msg != "", do: Logger.warning("TeslaApi.Error / #{msg}")
|
||||
{:error, reason}
|
||||
|
||||
@@ -386,6 +386,12 @@ defmodule TeslaMate.Vehicles.Vehicle do
|
||||
{:keep_state, data,
|
||||
[broadcast_fetch(false), broadcast_summary(), schedule_fetch(30, data)]}
|
||||
|
||||
{:error, :too_many_request, retry_after} ->
|
||||
Logger.error("Too many request / Retry after #{retry_after} seconds", car_id: data.car.id)
|
||||
|
||||
{:keep_state, data,
|
||||
[broadcast_fetch(false), broadcast_summary(), schedule_fetch(retry_after, data)]}
|
||||
|
||||
{:error, reason} ->
|
||||
Logger.error("Error / #{inspect(reason)}", car_id: data.car.id)
|
||||
|
||||
|
||||
@@ -343,6 +343,29 @@ defmodule TeslaMate.ApiTest do
|
||||
end
|
||||
end
|
||||
|
||||
@tag :capture_log
|
||||
test ":too_many_requests", %{test: name} do
|
||||
api_error = %TeslaApi.Error{
|
||||
reason: :too_many_requests,
|
||||
message: 300
|
||||
}
|
||||
|
||||
vehicle_mock =
|
||||
{TeslaApi.Vehicle, [],
|
||||
[
|
||||
get: fn _auth, _id -> {:error, api_error} end,
|
||||
get_with_state: fn _auth, _id -> {:error, api_error} end
|
||||
]}
|
||||
|
||||
with_mocks [auth_mock(self()), vehicle_mock] do
|
||||
:ok = start_api(name, start_auth: false)
|
||||
|
||||
assert :ok = Api.sign_in(name, @valid_tokens)
|
||||
assert {:error, :too_many_requests} = Api.get_vehicle(name, 0)
|
||||
assert {:error, :too_many_requests} = Api.get_vehicle_with_state(name, 0)
|
||||
end
|
||||
end
|
||||
|
||||
@tag :capture_log
|
||||
test "other error with Env", %{test: name} do
|
||||
api_error = %TeslaApi.Error{
|
||||
|
||||
Reference in New Issue
Block a user