From 0dafc9a81ea5d8876c6258d96eb452887a97ac56 Mon Sep 17 00:00:00 2001 From: Adam Renberg Tamm Date: Fri, 14 Jun 2024 16:15:26 +0200 Subject: [PATCH] Handle HTTP API error responses Signed-off-by: Adam Renberg Tamm --- lib/prometheus/api_client/client.rb | 5 +- spec/prometheus/api_client/client_spec.rb | 31 +++++++ .../prometheus/api_client/client.yml | 88 +++++++++++++++++++ 3 files changed, 123 insertions(+), 1 deletion(-) diff --git a/lib/prometheus/api_client/client.rb b/lib/prometheus/api_client/client.rb index bf78fa6..53cf1b8 100644 --- a/lib/prometheus/api_client/client.rb +++ b/lib/prometheus/api_client/client.rb @@ -104,7 +104,10 @@ def get(command, options) def run_command(command, options) response = get(command, options) - JSON.parse(response.body)['data'] + body = JSON.parse(response.body) + raise RequestError, body['error'] if body['status'] != 'success' + + body['data'] rescue StandardError => err raise RequestError, err.message end diff --git a/spec/prometheus/api_client/client_spec.rb b/spec/prometheus/api_client/client_spec.rb index f6a8889..64f9389 100644 --- a/spec/prometheus/api_client/client_spec.rb +++ b/spec/prometheus/api_client/client_spec.rb @@ -44,4 +44,35 @@ end end end + + describe '.run_command' do + it 'returns a hash' do + VCR.use_cassette('prometheus/api_client/client') do # , record: :new_episodes) do + prometheus = Prometheus::ApiClient::Client.new( + url: url, + credentials: { token: token }, + options: { verify_ssl: OpenSSL::SSL::VERIFY_NONE }, + ) + + response = prometheus.run_command( + "query_range", + { query: "up", start: "2015-07-01T20:10:30.781Z", end: "2015-07-01T20:11:00.781Z", step: "15s"} + ) + + expect(response).to eq({ "resultType"=>"matrix", "result"=>[], "explanation" => nil }) + end + end + + it 'raises on error' do + VCR.use_cassette('prometheus/api_client/client') do # , record: :new_episodes) do + prometheus = Prometheus::ApiClient::Client.new( + url: url, + credentials: { token: token }, + options: { verify_ssl: OpenSSL::SSL::VERIFY_NONE }, + ) + + expect { prometheus.run_command("query_ranage", { query: "(not a valid command"}) } .to raise_error(Prometheus::ApiClient::Client::RequestError) + end + end + end end diff --git a/spec/vcr_cassettes/prometheus/api_client/client.yml b/spec/vcr_cassettes/prometheus/api_client/client.yml index 0a96658..0e74a14 100644 --- a/spec/vcr_cassettes/prometheus/api_client/client.yml +++ b/spec/vcr_cassettes/prometheus/api_client/client.yml @@ -89,4 +89,92 @@ http_interactions: returned HTTP status 403 Forbidden","lastScrape":"2017-08-08T09:23:29.647620005Z","health":"down"},{"discoveredLabels":{"__address__":"10.128.0.7:8443","__meta_kubernetes_endpoint_port_name":"prometheus","__meta_kubernetes_endpoint_port_protocol":"TCP","__meta_kubernetes_endpoint_ready":"true","__meta_kubernetes_endpoints_name":"prometheus","__meta_kubernetes_namespace":"kube-system","__meta_kubernetes_pod_annotation_kubernetes_io_created_by":"{\"kind\":\"SerializedReference\",\"apiVersion\":\"v1\",\"reference\":{\"kind\":\"ReplicaSet\",\"namespace\":\"kube-system\",\"name\":\"prometheus-1552260379\",\"uid\":\"dada58d9-72aa-11e7-8221-001a4a2314d7\",\"apiVersion\":\"extensions\",\"resourceVersion\":\"3185\"}}\n","__meta_kubernetes_pod_annotation_openshift_io_scc":"restricted","__meta_kubernetes_pod_container_name":"oauth-proxy","__meta_kubernetes_pod_container_port_name":"web","__meta_kubernetes_pod_container_port_number":"8443","__meta_kubernetes_pod_container_port_protocol":"TCP","__meta_kubernetes_pod_host_ip":"10.35.19.248","__meta_kubernetes_pod_ip":"10.128.0.7","__meta_kubernetes_pod_label_app":"prometheus","__meta_kubernetes_pod_label_pod_template_hash":"1552260379","__meta_kubernetes_pod_name":"prometheus-1552260379-fq410","__meta_kubernetes_pod_node_name":"example.com","__meta_kubernetes_pod_ready":"true","__meta_kubernetes_service_annotation_openshift_io_generated_by":"OpenShiftNewApp","__meta_kubernetes_service_annotation_prometheus_io_scheme":"https","__meta_kubernetes_service_annotation_prometheus_io_scrape":"true","__meta_kubernetes_service_annotation_service_alpha_openshift_io_serving_cert_secret_name":"prometheus-tls","__meta_kubernetes_service_annotation_service_alpha_openshift_io_serving_cert_signed_by":"openshift-service-serving-signer@1501138614","__meta_kubernetes_service_label_name":"prometheus","__meta_kubernetes_service_name":"prometheus","__metrics_path__":"/metrics","__scheme__":"http","job":"kubernetes-service-endpoints"},"labels":{"instance":"10.128.0.7:8443","job":"kubernetes-service-endpoints","kubernetes_name":"prometheus","kubernetes_namespace":"kube-system","name":"prometheus"},"scrapeUrl":"https://10.128.0.7:8443/metrics","lastError":"","lastScrape":"2017-08-08T09:23:35.197491923Z","health":"up"}]}}' http_version: recorded_at: Tue, 08 Aug 2017 09:24:01 GMT +- request: + method: get + uri: https://prometheus.example.com/api/v1/query_range?end=2015-07-01T20:11:00.781Z&query=up&start=2015-07-01T20:10:30.781Z&step=15s + body: + encoding: US-ASCII + string: '' + headers: + Authorization: + - Bearer toSecret + User-Agent: + - Faraday v0.12.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Access-Control-Allow-Headers: + - Accept, Authorization, Content-Type, Origin + Access-Control-Allow-Methods: + - GET, OPTIONS + Access-Control-Allow-Origin: + - "*" + Access-Control-Expose-Headers: + - Date + Content-Type: + - application/json + Date: + - Tue, 08 Aug 2017 09:24:01 GMT + Transfer-Encoding: + - chunked + Set-Cookie: + - bd337c9bdedd23361d6a22bfc4876b73=44e5e3f1c41ffda8509c6f9fbf8b9402; path=/; + HttpOnly; Secure + Cache-Control: + - private + body: + encoding: UTF-8 + string: '{"status":"success","data":{"resultType":"matrix","result":[],"explanation":null}}' + http_version: + recorded_at: Tue, 08 Aug 2017 09:24:01 GMT +- request: + method: get + uri: https://prometheus.example.com/api/v1/query_ranage?query=(not%20a%20valid%20command + body: + encoding: US-ASCII + string: '' + headers: + Authorization: + - Bearer toSecret + User-Agent: + - Faraday v0.12.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Access-Control-Allow-Headers: + - Accept, Authorization, Content-Type, Origin + Access-Control-Allow-Methods: + - GET, OPTIONS + Access-Control-Allow-Origin: + - "*" + Access-Control-Expose-Headers: + - Date + Content-Type: + - application/json + Date: + - Tue, 08 Aug 2017 09:24:01 GMT + Transfer-Encoding: + - chunked + Set-Cookie: + - bd337c9bdedd23361d6a22bfc4876b73=44e5e3f1c41ffda8509c6f9fbf8b9402; path=/; + HttpOnly; Secure + Cache-Control: + - private + body: + encoding: UTF-8 + string: '{"status": "error", "error": "1:6: parse error: unexpected identifier \"a\""}' + http_version: + recorded_at: Tue, 08 Aug 2017 09:24:01 GMT recorded_with: VCR 3.0.3