Skip to content

Commit 3795aee

Browse files
authored
Merge pull request #423 from seanpdoyle/rescuable
Mix-in `ActiveSupport::Rescuable`
2 parents d711053 + 01be7dd commit 3795aee

File tree

4 files changed

+113
-1
lines changed

4 files changed

+113
-1
lines changed

lib/active_resource.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ module ActiveResource
4141
autoload :CustomMethods
4242
autoload :Formats
4343
autoload :HttpMock
44+
autoload :Rescuable
4445
autoload :Schema
4546
autoload :Singleton
4647
autoload :InheritingHash

lib/active_resource/base.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1443,6 +1443,8 @@ def encode(options = {})
14431443
# my_branch.name # => "Wilson Road"
14441444
def reload
14451445
self.load(self.class.find(to_param, params: @prefix_options).attributes, false, true)
1446+
rescue => exception
1447+
rescue_with_handler(exception) || raise
14461448
end
14471449

14481450
# A method to manually load attributes from a \hash. Recursively loads collections of
@@ -1725,7 +1727,7 @@ class Base
17251727
include ActiveModel::Conversion
17261728
include ActiveModel::Serializers::JSON
17271729
include ActiveModel::Serializers::Xml
1728-
include ActiveResource::Reflection
1730+
include ActiveResource::Reflection, ActiveResource::Rescuable
17291731
end
17301732

17311733
ActiveSupport.run_load_hooks(:active_resource, Base)

lib/active_resource/rescuable.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# frozen_string_literal: true
2+
3+
module ActiveResource
4+
# = Active Resource \Rescuable
5+
#
6+
# Provides
7+
# {rescue_from}[rdoc-ref:ActiveSupport::Rescuable::ClassMethods#rescue_from]
8+
# for resources. Wraps calls over the network to handle configured errors.
9+
module Rescuable
10+
extend ActiveSupport::Concern
11+
12+
included do
13+
include ActiveSupport::Rescuable
14+
15+
around_save :handle_exceptions
16+
around_destroy :handle_exceptions
17+
end
18+
19+
private
20+
def handle_exceptions
21+
yield
22+
rescue => exception
23+
rescue_with_handler(exception) || raise
24+
end
25+
end
26+
end

test/cases/rescuable_test.rb

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# frozen_string_literal: true
2+
3+
require "abstract_unit"
4+
require "fixtures/person"
5+
6+
class RescuableTest < ActiveSupport::TestCase
7+
class Rescuable < ActiveResource::Base
8+
class Error < StandardError
9+
end
10+
11+
self.site = "http://37s.sunrise.i:3000"
12+
13+
rescue_from ActiveResource::ResourceNotFound, with: :rescue_not_found
14+
rescue_from ActiveResource::UnauthorizedAccess, with: :rescue_unauthorized
15+
rescue_from ActiveResource::BadRequest, with: ->(*) { raise Error, "Bad Request" }
16+
17+
schema do
18+
attribute :not_found, :boolean
19+
attribute :unauthorized, :boolean
20+
end
21+
22+
def rescue_not_found
23+
self.not_found = true
24+
end
25+
26+
def rescue_unauthorized
27+
self.unauthorized = true
28+
end
29+
end
30+
31+
def test_rescue_from_catches_exceptions_raised_during_reload
32+
ActiveResource::HttpMock.respond_to.get "/rescuables/1.json", {}, nil, 404
33+
resource = Rescuable.new({ id: 1 }, true)
34+
35+
assert_nothing_raised { resource.reload }
36+
37+
assert_predicate resource, :not_found?
38+
end
39+
40+
def test_rescue_from_catches_exceptions_raised_during_create
41+
ActiveResource::HttpMock.respond_to.post "/rescuables.json", {}, nil, 401
42+
resource = Rescuable.new
43+
44+
assert_nothing_raised { resource.save! }
45+
46+
assert_predicate resource, :unauthorized?
47+
end
48+
49+
def test_rescue_from_catches_exceptions_raised_during_destroy
50+
ActiveResource::HttpMock.respond_to.delete "/rescuables/1.json", {}, nil, 401
51+
resource = Rescuable.new({ id: 1 }, true)
52+
53+
assert_nothing_raised { resource.destroy }
54+
55+
assert_predicate resource, :unauthorized?
56+
end
57+
58+
def test_rescue_from_catches_exceptions_raised_during_save
59+
ActiveResource::HttpMock.respond_to.put "/rescuables/1.json", {}, nil, 401
60+
resource = Rescuable.new({ id: 1 }, true)
61+
62+
assert_nothing_raised { resource.save! }
63+
64+
assert_predicate resource, :unauthorized?
65+
end
66+
67+
def test_rescue_from_catches_exceptions_raised_during_update
68+
ActiveResource::HttpMock.respond_to.put "/rescuables/1.json", {}, nil, 401
69+
resource = Rescuable.new({ id: 1 }, true)
70+
71+
assert_nothing_raised { resource.update_attributes(saved: true) }
72+
73+
assert_predicate resource, :unauthorized?
74+
end
75+
76+
def test_rescue_from_re_raises_exceptions_raised_during_save
77+
ActiveResource::HttpMock.respond_to.post "/rescuables.json", {}, {}, 400
78+
79+
assert_raises Rescuable::Error, match: "Bad Request" do
80+
Rescuable.create!
81+
end
82+
end
83+
end

0 commit comments

Comments
 (0)