diff --git a/lib/easee/client.rb b/lib/easee/client.rb index 86c03ef..ddaad9a 100644 --- a/lib/easee/client.rb +++ b/lib/easee/client.rb @@ -176,8 +176,13 @@ def store_tokens(tokens) end def raise_credentials_or_request_error(error) - if error.response_status == 400 && [100, 727].include?(error.response.dig(:body, "errorCode")) + case error.response&.dig(:body, "errorCode") + when *Errors::InvalidCredentials::CODES raise Errors::InvalidCredentials, "Invalid username or password" + when Errors::InvalidPinCode::CODE + raise Errors::InvalidPinCode.new("PIN code rejected", error.response) + when Errors::ChargerNotFound::CODE + raise Errors::ChargerNotFound.new("Charger not found", error.response) end raise request_failed(error) diff --git a/lib/easee/errors.rb b/lib/easee/errors.rb index 1fed566..e1c6eaa 100644 --- a/lib/easee/errors.rb +++ b/lib/easee/errors.rb @@ -4,7 +4,9 @@ class Base < ::StandardError def retryable? = false end - class InvalidCredentials < Base; end + class InvalidCredentials < Base + CODES = [100, 727].freeze + end class RequestFailed < Base attr_reader :response @@ -17,6 +19,14 @@ def initialize(message, response = nil) class Forbidden < Base; end + class InvalidPinCode < RequestFailed + CODE = 193 + end + + class ChargerNotFound < RequestFailed + CODE = 400 + end + class RateLimitExceeded < RequestFailed def retryable? = true end diff --git a/spec/easee/client_spec.rb b/spec/easee/client_spec.rb index 413ae43..fc0f2cb 100644 --- a/spec/easee/client_spec.rb +++ b/spec/easee/client_spec.rb @@ -317,6 +317,56 @@ expect { client.pair(charger_id: "123ABC", pin_code: "1234") }.not_to raise_error end + + it "raises InvalidPinCode when Easee rejects the PIN (errorCode 193)" do + token_cache = ActiveSupport::Cache::MemoryStore.new + token_cache.write( + Easee::Client::TOKENS_CACHE_KEY, + { "accessToken" => "T123" }.to_json, + ) + + stub_request(:post, "https://api.easee.cloud/api/chargers/123ABC/pair?pinCode=WRONG") + .with(headers: { "Authorization" => "Bearer T123" }) + .to_return( + status: 400, + body: { + errorCode: 193, + errorCodeName: "NotPossibleToGrantAccessWithPinCode", + title: "Not possible to grant access with pin code", + }.to_json, + headers: { "Content-Type": "application/json" }, + ) + + client = Easee::Client.new(user_name: "easee", password: "money", token_cache:) + + expect { client.pair(charger_id: "123ABC", pin_code: "WRONG") } + .to raise_error(Easee::Errors::InvalidPinCode) + end + + it "raises ChargerNotFound when the charger is unknown (errorCode 400)" do + token_cache = ActiveSupport::Cache::MemoryStore.new + token_cache.write( + Easee::Client::TOKENS_CACHE_KEY, + { "accessToken" => "T123" }.to_json, + ) + + stub_request(:post, "https://api.easee.cloud/api/chargers/UNKNOWN/pair?pinCode=1234") + .with(headers: { "Authorization" => "Bearer T123" }) + .to_return( + status: 404, + body: { + errorCode: 400, + errorCodeName: "ChargerNotFound", + title: "Charger not found", + }.to_json, + headers: { "Content-Type": "application/json" }, + ) + + client = Easee::Client.new(user_name: "easee", password: "money", token_cache:) + + expect { client.pair(charger_id: "UNKNOWN", pin_code: "1234") } + .to raise_error(Easee::Errors::ChargerNotFound) + end end describe "#unpair" do