diff --git a/lib/zaptec/client.rb b/lib/zaptec/client.rb index a6d9e2d..5856125 100644 --- a/lib/zaptec/client.rb +++ b/lib/zaptec/client.rb @@ -73,8 +73,18 @@ def get_installation(installation_id) # https://api.zaptec.com/help/index.html#/Installation/get_api_installation__id__hierarchy def get_installation_hierarchy(installation_id) - get("/api/installation/#{installation_id}/hierarchy") - .then { |response| InstallationHierarchy.new(response.body) } + response = get("/api/installation/#{installation_id}/hierarchy") + + if response.status == 204 + sleep 2 + response = get("/api/installation/#{installation_id}/hierarchy") + end + + if response.status == 204 + raise Errors::RequestFailed.new("Empty response for installation hierarchy", response) + end + + InstallationHierarchy.new(response.body) end # https://api.zaptec.com/help/index.html#/Charger/get_api_chargers__id__state diff --git a/spec/zaptec/client_spec.rb b/spec/zaptec/client_spec.rb index e94a6f6..394b5d7 100644 --- a/spec/zaptec/client_spec.rb +++ b/spec/zaptec/client_spec.rb @@ -505,6 +505,46 @@ name: "Zaptec", ) end + + it "retries once after a 204 response" do + hierarchy_body = { + Id: "2bbec6f9-c3ce-4edf-a72f-b1b2a663c6ba", + Name: "Stekker test", + NetworkType: 4, + Circuits: [], + }.to_json + + WebMock::API + .stub_request(:get, "https://api.zaptec.com/api/installation/I123/hierarchy") + .to_return( + { status: 204, body: "", headers: {} }, + { status: 200, body: hierarchy_body, headers: { "Content-Type": "application/json" } }, + ) + + token_cache = build_token_cache("T123") + client = Zaptec::Client.new(username: "zap", password: "tec", token_cache:) + + allow(client).to receive(:sleep) + + installation_hierarchy = client.get_installation_hierarchy("I123") + + expect(installation_hierarchy.name).to eq("Stekker test") + expect(client).to have_received(:sleep).with(2) + end + + it "raises RequestFailed after two consecutive 204 responses" do + WebMock::API + .stub_request(:get, "https://api.zaptec.com/api/installation/I123/hierarchy") + .to_return(status: 204, body: "", headers: {}) + + token_cache = build_token_cache("T123") + client = Zaptec::Client.new(username: "zap", password: "tec", token_cache:) + + allow(client).to receive(:sleep) + + expect { client.get_installation_hierarchy("I123") } + .to raise_error(Zaptec::Errors::RequestFailed, "Empty response for installation hierarchy") + end end describe "#get_installation" do