Skip to content

Commit

Permalink
Merge pull request #97 from dchandekstark/retriable-exceptions
Browse files Browse the repository at this point in the history
Version 1.10.0
  • Loading branch information
dchandekstark authored Mar 21, 2024
2 parents 89d3d2b + 7b5b3b3 commit b2d7531
Show file tree
Hide file tree
Showing 8 changed files with 37 additions and 25 deletions.
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
.bundle
.config
.dockerignore
.git
.github
.gitignore
Dockerfile
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ruby.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
ruby-version: ['2.7', '3.0', '3.1', '3.2']
ruby-version: ['3.0', '3.1', '3.2', '3.3']

steps:
- uses: actions/checkout@v2
Expand Down
8 changes: 4 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ FROM ruby:${ruby_version}

SHELL ["/bin/bash", "-c"]

RUN gem install bundler -v '~>2.0'

WORKDIR /app

COPY . .
COPY VERSION Gemfile ezid-client.gemspec ./

RUN bundle install
RUN gem install bundler -v '~>2.0' && bundle install

COPY . .
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.9.4
1.10.0
2 changes: 2 additions & 0 deletions lib/ezid/error.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@ class NotAllowedError < Error; end
class DeletionError < Error; end

class UnexpectedResponseError < Error; end

class ServerError < Error; end
end
30 changes: 25 additions & 5 deletions lib/ezid/requests/request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ class Request < SimpleDelegator
POST = Net::HTTP::Post
DELETE = Net::HTTP::Delete

RETRIABLE_SERVER_ERRORS = %w[500 502 503 504].freeze

RETRIES = ENV.fetch('EZID_REQUEST_RETRIES', '2').to_i

class << self
attr_accessor :http_method, :path, :response_class

Expand All @@ -37,7 +41,7 @@ def short_name
end

attr_reader :client
def_delegators :client, :connection, :user, :password, :session
def_delegators :client, :connection, :user, :password, :session, :logger, :config

# @param client [Ezid::Client] the client
def initialize(client, *args)
Expand All @@ -50,12 +54,24 @@ def initialize(client, *args)
# @return [Ezid::Response] the response
def execute
retries = 0

begin
response_class.new(get_response_for_request)
rescue Net::HTTPServerException, UnexpectedResponseError => e
if retries < 2
sleep client.config.retry_interval
http_response = get_response_for_request

if RETRIABLE_SERVER_ERRORS.include? http_response.code
raise ServerError, "#{http_response.code} #{http_response.msg}"
end

response_class.new(http_response)

rescue ServerError, UnexpectedResponseError => e
if retries < RETRIES
logger.error "EZID error: #{e}"

retries += 1
logger.info "Retry (#{retries} of #{RETRIES}) of #{short_name} #{path} in #{config.retry_interval} seconds ..."
sleep config.retry_interval

retry
else
raise
Expand Down Expand Up @@ -85,6 +101,10 @@ def response_class
# @return [String] the query string
def query; end

def short_name
self.class.short_name
end

def authentication_required?
true
end
Expand Down
2 changes: 0 additions & 2 deletions lib/ezid/responses/response.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ class Response < SimpleDelegator
ERROR = "error".freeze

def initialize(http_response)
http_response.value # raises Net::HTTPServerException

super

unless status_line =~ /^(#{SUCCESS}|#{ERROR}): /
Expand Down
15 changes: 3 additions & 12 deletions spec/unit/client_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -179,16 +179,6 @@ module Ezid
allow(GetIdentifierMetadataRequest).to receive(:execute).with(subject, "invalid") { stub_response }
end

describe "HTTP error response" do
before do
allow(http_response).to receive(:value).and_raise(Net::HTTPServerException.new('Barf!', double))
end

it "raises an exception" do
expect { subject.get_identifier_metadata("invalid") }.to raise_error(Net::HTTPServerException)
end
end

describe "EZID API error response" do
let(:body) { "error: bad request - no such identifier" }

Expand Down Expand Up @@ -220,11 +210,12 @@ module Ezid

describe "retrying on certain errors" do
before do
allow(subject.config).to receive(:retry_interval) { 1 }
allow(GetIdentifierMetadataResponse).to receive(:new).and_raise(exception)
end

describe "HTTP error" do
let(:exception) { Net::HTTPServerException.new('Barf!', double) }
describe "retriable server error" do
let(:exception) { ServerError.new('502 Bad Gateway') }

it "retries twice" do
begin
Expand Down

0 comments on commit b2d7531

Please sign in to comment.