Skip to content

Mix-in ActiveSupport::Rescuable #423

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/active_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ module ActiveResource
autoload :CustomMethods
autoload :Formats
autoload :HttpMock
autoload :Rescuable
autoload :Schema
autoload :Singleton
autoload :InheritingHash
Expand Down
4 changes: 3 additions & 1 deletion lib/active_resource/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1443,6 +1443,8 @@ def encode(options = {})
# my_branch.name # => "Wilson Road"
def reload
self.load(self.class.find(to_param, params: @prefix_options).attributes, false, true)
rescue => exception
rescue_with_handler(exception) || raise
Comment on lines +1446 to +1447
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If #414 were merged, this change could be removed in favor of a matching declaration in ActiveResource::Rescuable:

around_reload :rescue_exceptions

end

# A method to manually load attributes from a \hash. Recursively loads collections of
Expand Down Expand Up @@ -1725,7 +1727,7 @@ class Base
include ActiveModel::Conversion
include ActiveModel::Serializers::JSON
include ActiveModel::Serializers::Xml
include ActiveResource::Reflection
include ActiveResource::Reflection, ActiveResource::Rescuable
end

ActiveSupport.run_load_hooks(:active_resource, Base)
Expand Down
26 changes: 26 additions & 0 deletions lib/active_resource/rescuable.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# frozen_string_literal: true

module ActiveResource
# = Active Resource \Rescuable
#
# Provides
# {rescue_from}[rdoc-ref:ActiveSupport::Rescuable::ClassMethods#rescue_from]
# for resources. Wraps calls over the network to handle configured errors.
module Rescuable
extend ActiveSupport::Concern

included do
include ActiveSupport::Rescuable

around_save :handle_exceptions
around_destroy :handle_exceptions
end

private
def handle_exceptions
yield
rescue => exception
rescue_with_handler(exception) || raise
end
end
end
83 changes: 83 additions & 0 deletions test/cases/rescuable_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# frozen_string_literal: true

require "abstract_unit"
require "fixtures/person"

class RescuableTest < ActiveSupport::TestCase
class Rescuable < ActiveResource::Base
class Error < StandardError
end

self.site = "http://37s.sunrise.i:3000"

rescue_from ActiveResource::ResourceNotFound, with: :rescue_not_found
rescue_from ActiveResource::UnauthorizedAccess, with: :rescue_unauthorized
rescue_from ActiveResource::BadRequest, with: ->(*) { raise Error, "Bad Request" }

schema do
attribute :not_found, :boolean
attribute :unauthorized, :boolean
end

def rescue_not_found
self.not_found = true
end

def rescue_unauthorized
self.unauthorized = true
end
end

def test_rescue_from_catches_exceptions_raised_during_reload
ActiveResource::HttpMock.respond_to.get "/rescuables/1.json", {}, nil, 404
resource = Rescuable.new({ id: 1 }, true)

assert_nothing_raised { resource.reload }

assert_predicate resource, :not_found?
end

def test_rescue_from_catches_exceptions_raised_during_create
ActiveResource::HttpMock.respond_to.post "/rescuables.json", {}, nil, 401
resource = Rescuable.new

assert_nothing_raised { resource.save! }

assert_predicate resource, :unauthorized?
end

def test_rescue_from_catches_exceptions_raised_during_destroy
ActiveResource::HttpMock.respond_to.delete "/rescuables/1.json", {}, nil, 401
resource = Rescuable.new({ id: 1 }, true)

assert_nothing_raised { resource.destroy }

assert_predicate resource, :unauthorized?
end

def test_rescue_from_catches_exceptions_raised_during_save
ActiveResource::HttpMock.respond_to.put "/rescuables/1.json", {}, nil, 401
resource = Rescuable.new({ id: 1 }, true)

assert_nothing_raised { resource.save! }

assert_predicate resource, :unauthorized?
end

def test_rescue_from_catches_exceptions_raised_during_update
ActiveResource::HttpMock.respond_to.put "/rescuables/1.json", {}, nil, 401
resource = Rescuable.new({ id: 1 }, true)

assert_nothing_raised { resource.update_attributes(saved: true) }

assert_predicate resource, :unauthorized?
end

def test_rescue_from_re_raises_exceptions_raised_during_save
ActiveResource::HttpMock.respond_to.post "/rescuables.json", {}, {}, 400

assert_raises Rescuable::Error, match: "Bad Request" do
Rescuable.create!
end
end
end
Loading