From 37f34276cb485a133525a0408e9c6141863f30d2 Mon Sep 17 00:00:00 2001 From: Emiliano Mancuso Date: Thu, 6 May 2021 11:42:17 +0100 Subject: [PATCH 1/2] Add extra error classes to handle server errors. In order to provide more granularity on the exceptions, we are adding some additional error classes for the common Server errors. --- lib/json_api_client/errors.rb | 36 ++++++++++++++++-------- lib/json_api_client/middleware/status.rb | 8 ++++++ test/unit/errors_test.rb | 36 ++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 12 deletions(-) diff --git a/lib/json_api_client/errors.rb b/lib/json_api_client/errors.rb index 712b9900..0d1e354d 100644 --- a/lib/json_api_client/errors.rb +++ b/lib/json_api_client/errors.rb @@ -44,6 +44,25 @@ class AccessDenied < ClientError class NotAuthorized < ClientError end + class NotFound < ClientError + attr_reader :uri + def initialize(uri) + @uri = uri + + msg = "Couldn't find resource at: #{uri.to_s}" + super nil, msg + end + end + + class Conflict < ClientError + def initialize(env, msg = 'Resource already exists') + super env, msg + end + end + + class TooManyRequests < ClientError + end + class ConnectionError < ApiError end @@ -59,23 +78,16 @@ def initialize(env, msg = nil) end end - class Conflict < ServerError - def initialize(env, msg = 'Resource already exists') - super env, msg - end + class InternalServerError < ServerError end - class NotFound < ServerError - attr_reader :uri - def initialize(uri) - @uri = uri + class BadGateway < ServerError + end - msg = "Couldn't find resource at: #{uri.to_s}" - super nil, msg - end + class ServiceUnavailable < ServerError end - class InternalServerError < ServerError + class GatewayTimeout < ServerError end class UnexpectedStatus < ServerError diff --git a/lib/json_api_client/middleware/status.rb b/lib/json_api_client/middleware/status.rb index 223f4aa3..545130cc 100644 --- a/lib/json_api_client/middleware/status.rb +++ b/lib/json_api_client/middleware/status.rb @@ -42,10 +42,18 @@ def handle_status(code, env) raise Errors::Conflict, env when 422 # Allow to proceed as resource errors will be populated + when 429 + raise Errors::TooManyRequests, env when 400..499 raise Errors::ClientError, env when 500 raise Errors::InternalServerError, env + when 502 + raise Errors::BadGateway, env + when 503 + raise Errors::ServiceUnavailable, env + when 504 + raise Errors::GatewayTimeout, env when 501..599 raise Errors::ServerError, env else diff --git a/test/unit/errors_test.rb b/test/unit/errors_test.rb index 0627f134..7f272d2f 100644 --- a/test/unit/errors_test.rb +++ b/test/unit/errors_test.rb @@ -96,6 +96,42 @@ def test_not_authorized end end + def test_too_many_requests + stub_request(:get, "http://example.com/users") + .to_return(headers: {content_type: "text/plain"}, status: 429, body: "too many requests") + + assert_raises JsonApiClient::Errors::TooManyRequests do + User.all + end + end + + def test_bad_gateway + stub_request(:get, "http://example.com/users") + .to_return(headers: {content_type: "text/plain"}, status: 502, body: "bad gateway") + + assert_raises JsonApiClient::Errors::BadGateway do + User.all + end + end + + def test_service_unavailable + stub_request(:get, "http://example.com/users") + .to_return(headers: {content_type: "text/plain"}, status: 503, body: "service unavailable") + + assert_raises JsonApiClient::Errors::ServiceUnavailable do + User.all + end + end + + def test_gateway_timeout + stub_request(:get, "http://example.com/users") + .to_return(headers: {content_type: "text/plain"}, status: 504, body: "gateway timeout") + + assert_raises JsonApiClient::Errors::GatewayTimeout do + User.all + end + end + def test_errors_are_rescuable_by_default_rescue begin raise JsonApiClient::Errors::ApiError, "Something bad happened" From f407acdaabec24011fa21bae1cfec73b9fae0e64 Mon Sep 17 00:00:00 2001 From: Emiliano Mancuso Date: Thu, 6 May 2021 12:21:54 +0100 Subject: [PATCH 2/2] Add 408-RequestTimeout class --- lib/json_api_client/errors.rb | 3 +++ lib/json_api_client/middleware/status.rb | 2 ++ test/unit/errors_test.rb | 9 +++++++++ 3 files changed, 14 insertions(+) diff --git a/lib/json_api_client/errors.rb b/lib/json_api_client/errors.rb index 0d1e354d..795235c4 100644 --- a/lib/json_api_client/errors.rb +++ b/lib/json_api_client/errors.rb @@ -54,6 +54,9 @@ def initialize(uri) end end + class RequestTimeout < ClientError + end + class Conflict < ClientError def initialize(env, msg = 'Resource already exists') super env, msg diff --git a/lib/json_api_client/middleware/status.rb b/lib/json_api_client/middleware/status.rb index 545130cc..37f69a70 100644 --- a/lib/json_api_client/middleware/status.rb +++ b/lib/json_api_client/middleware/status.rb @@ -38,6 +38,8 @@ def handle_status(code, env) raise Errors::AccessDenied, env when 404 raise Errors::NotFound, env[:url] + when 408 + raise Errors::RequestTimeout, env when 409 raise Errors::Conflict, env when 422 diff --git a/test/unit/errors_test.rb b/test/unit/errors_test.rb index 7f272d2f..6d533598 100644 --- a/test/unit/errors_test.rb +++ b/test/unit/errors_test.rb @@ -96,6 +96,15 @@ def test_not_authorized end end + def test_request_timeout + stub_request(:get, "http://example.com/users") + .to_return(headers: {content_type: "text/plain"}, status: 408, body: "request timeout") + + assert_raises JsonApiClient::Errors::RequestTimeout do + User.all + end + end + def test_too_many_requests stub_request(:get, "http://example.com/users") .to_return(headers: {content_type: "text/plain"}, status: 429, body: "too many requests")