acfs 1.3.2 → 1.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +39 -0
  3. data/README.md +10 -23
  4. data/acfs.gemspec +19 -20
  5. data/lib/acfs.rb +2 -0
  6. data/lib/acfs/adapter/base.rb +6 -8
  7. data/lib/acfs/adapter/typhoeus.rb +25 -6
  8. data/lib/acfs/collection.rb +2 -1
  9. data/lib/acfs/collections/paginatable.rb +4 -3
  10. data/lib/acfs/configuration.rb +14 -7
  11. data/lib/acfs/errors.rb +60 -19
  12. data/lib/acfs/global.rb +2 -0
  13. data/lib/acfs/location.rb +9 -5
  14. data/lib/acfs/middleware/base.rb +5 -1
  15. data/lib/acfs/middleware/json.rb +6 -2
  16. data/lib/acfs/middleware/logger.rb +2 -0
  17. data/lib/acfs/middleware/msgpack.rb +2 -0
  18. data/lib/acfs/middleware/print.rb +2 -0
  19. data/lib/acfs/middleware/serializer.rb +2 -0
  20. data/lib/acfs/operation.rb +20 -3
  21. data/lib/acfs/request.rb +5 -1
  22. data/lib/acfs/request/callbacks.rb +5 -1
  23. data/lib/acfs/resource.rb +2 -0
  24. data/lib/acfs/resource/attributes.rb +7 -4
  25. data/lib/acfs/resource/attributes/base.rb +2 -1
  26. data/lib/acfs/resource/attributes/boolean.rb +2 -0
  27. data/lib/acfs/resource/attributes/date_time.rb +3 -2
  28. data/lib/acfs/resource/attributes/dict.rb +2 -0
  29. data/lib/acfs/resource/attributes/float.rb +5 -3
  30. data/lib/acfs/resource/attributes/integer.rb +2 -0
  31. data/lib/acfs/resource/attributes/list.rb +2 -0
  32. data/lib/acfs/resource/attributes/string.rb +2 -0
  33. data/lib/acfs/resource/attributes/uuid.rb +4 -3
  34. data/lib/acfs/resource/dirty.rb +2 -0
  35. data/lib/acfs/resource/initialization.rb +2 -0
  36. data/lib/acfs/resource/loadable.rb +2 -0
  37. data/lib/acfs/resource/locatable.rb +10 -6
  38. data/lib/acfs/resource/operational.rb +2 -1
  39. data/lib/acfs/resource/persistence.rb +7 -6
  40. data/lib/acfs/resource/query_methods.rb +6 -4
  41. data/lib/acfs/resource/service.rb +3 -1
  42. data/lib/acfs/resource/validation.rb +19 -7
  43. data/lib/acfs/response.rb +2 -0
  44. data/lib/acfs/response/formats.rb +2 -0
  45. data/lib/acfs/response/status.rb +3 -1
  46. data/lib/acfs/rspec.rb +2 -0
  47. data/lib/acfs/runner.rb +6 -1
  48. data/lib/acfs/service.rb +24 -13
  49. data/lib/acfs/service/middleware.rb +2 -0
  50. data/lib/acfs/service/middleware/stack.rb +5 -3
  51. data/lib/acfs/singleton_resource.rb +4 -2
  52. data/lib/acfs/stub.rb +32 -11
  53. data/lib/acfs/util.rb +2 -0
  54. data/lib/acfs/version.rb +4 -2
  55. data/lib/acfs/yard.rb +1 -0
  56. data/spec/acfs/adapter/typhoeus_spec.rb +30 -3
  57. data/spec/acfs/collection_spec.rb +7 -5
  58. data/spec/acfs/configuration_spec.rb +2 -0
  59. data/spec/acfs/global_spec.rb +6 -3
  60. data/spec/acfs/location_spec.rb +2 -0
  61. data/spec/acfs/middleware/json_spec.rb +17 -1
  62. data/spec/acfs/middleware/msgpack_spec.rb +2 -0
  63. data/spec/acfs/operation_spec.rb +2 -0
  64. data/spec/acfs/request/callbacks_spec.rb +2 -0
  65. data/spec/acfs/request_spec.rb +3 -1
  66. data/spec/acfs/resource/attributes/boolean_spec.rb +2 -0
  67. data/spec/acfs/resource/attributes/date_time_spec.rb +2 -0
  68. data/spec/acfs/resource/attributes/dict_spec.rb +4 -2
  69. data/spec/acfs/resource/attributes/float_spec.rb +3 -1
  70. data/spec/acfs/resource/attributes/integer_spec.rb +2 -0
  71. data/spec/acfs/resource/attributes/list_spec.rb +5 -3
  72. data/spec/acfs/resource/attributes/uuid_spec.rb +2 -0
  73. data/spec/acfs/resource/attributes_spec.rb +8 -8
  74. data/spec/acfs/resource/dirty_spec.rb +2 -0
  75. data/spec/acfs/resource/initialization_spec.rb +8 -2
  76. data/spec/acfs/resource/loadable_spec.rb +2 -0
  77. data/spec/acfs/resource/locatable_spec.rb +2 -0
  78. data/spec/acfs/resource/persistance_spec.rb +10 -4
  79. data/spec/acfs/resource/query_methods_spec.rb +24 -17
  80. data/spec/acfs/resource/validation_spec.rb +2 -0
  81. data/spec/acfs/response/formats_spec.rb +3 -1
  82. data/spec/acfs/response/status_spec.rb +2 -0
  83. data/spec/acfs/runner_spec.rb +6 -8
  84. data/spec/acfs/service/middleware_spec.rb +2 -0
  85. data/spec/acfs/service_spec.rb +3 -1
  86. data/spec/acfs/singleton_resource_spec.rb +2 -0
  87. data/spec/acfs/stub_spec.rb +2 -0
  88. data/spec/acfs_spec.rb +2 -0
  89. data/spec/spec_helper.rb +3 -1
  90. data/spec/support/hash.rb +2 -0
  91. data/spec/support/response.rb +2 -0
  92. data/spec/support/service.rb +1 -0
  93. data/spec/support/shared/find_callbacks.rb +2 -0
  94. metadata +26 -26
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9e970f81dff63a351279207100701f7a9be822272a77e5dfc3bd39d9e418a0db
4
- data.tar.gz: 81b752674659595a097b951334bb41fa36f9a96de2f3b7ff0a1a82d3e03f0009
3
+ metadata.gz: 55e1388e9df4207138b2a54f1e9d56c349ac407e52364b849887e9682abfee7e
4
+ data.tar.gz: ccf1b3550de8f5222988333d14e480ec07742fb0398d3adfb9504be4ca4168b4
5
5
  SHA512:
6
- metadata.gz: 4d8363f66d917672285318eaf1f68f03c3ef28c560373b4e74054f5d5d4da7dd0a443f6b54c9835fafbd290921e2d8316195a3c015970e539baa37fb8bead339
7
- data.tar.gz: 73d009dc5601ba4e4cc06efb41a0990a58779726b86ebf4905c2967dba55de406085b83e9a7c3de71b860e748bae1ff39b2a59de91a2699c488ced2d689d9234
6
+ metadata.gz: d34c6fd3d4e83e22757633efc72c8d399778b86665f4b5bb6fb46c8d4f93782f996fe307904ac83f9b16701157ecb8418977466cad9d9c5a78c6ea1074e9ddd7
7
+ data.tar.gz: 3460436cd3a9d61241155658e4c46ef556b69d00fd389aca73c78ca6484b29bac9b3c45a0fd310b41259aba68f8aad55c7ca95a259e18075c2d88b2515bacd52
@@ -14,6 +14,45 @@
14
14
  ### Breaks
15
15
 
16
16
 
17
+ ## 1.5.1 - (2020-12-30)
18
+ ---
19
+
20
+ ### Changes
21
+ * Revert back to using `::MultiJson`
22
+
23
+
24
+ ## 1.5.0 - (2020-06-19)
25
+ ---
26
+
27
+ ### New
28
+ * Error classes for more HTTP error responses: `400`, `401`, `403`, `500`, `502`, `503`, `504`.
29
+
30
+ ### Changes
31
+ * Replace deprecated MultiJson with core JSON module
32
+
33
+
34
+ ## 1.4.0 - (2020-06-12)
35
+ ---
36
+
37
+ ### New
38
+ * Use strict TCP keepalive probing by default (5s/5s)
39
+ * Adapter accepts curl request opts
40
+
41
+
42
+ ## 1.3.4 - (2020-03-22)
43
+ ---
44
+
45
+ ### Fixes
46
+ * Empty package build for Gem release 1.3.3
47
+
48
+
49
+ ## 1.3.3 - (2020-03-22)
50
+ ---
51
+
52
+ ### Changes
53
+ * Improved handling of low-level connection errors and timeouts
54
+
55
+
17
56
  ## 1.3.2 - (2019-09-24)
18
57
 
19
58
 
data/README.md CHANGED
@@ -1,7 +1,8 @@
1
1
  # Acfs - *API client for services*
2
2
 
3
- [![Gem Version](https://badge.fury.io/rb/acfs.svg)](http://badge.fury.io/rb/acfs)
4
- [![Build Status](http://img.shields.io/travis/jgraichen/acfs/master.svg)](https://travis-ci.org/jgraichen/acfs)
3
+ [![Gem Version](https://img.shields.io/gem/v/acfs?logo=ruby)](https://rubygems.org/gems/acfs)
4
+ [![Build Status](https://img.shields.io/travis/jgraichen/acfs/master?logo=travis)](https://travis-ci.org/jgraichen/acfs)
5
+ [![GitHub Workflow Status](https://img.shields.io/github/workflow/status/jgraichen/acfs/Test/master?logo=github)](https://github.com/jgraichen/acfs/actions?query=branch%3Amaster)
5
6
  [![Coverage Status](http://img.shields.io/coveralls/jgraichen/acfs/master.svg)](https://coveralls.io/r/jgraichen/acfs)
6
7
  [![RubyDoc Documentation](http://img.shields.io/badge/rubydoc-here-blue.svg)](http://rubydoc.info/github/jgraichen/acfs/master/frames)
7
8
 
@@ -9,6 +10,7 @@ Acfs is a library to develop API client libraries for single services within a l
9
10
 
10
11
  Acfs covers model and service abstraction, convenient query and filter methods, full middleware stack for pre-processing requests and responses on a per service level and automatic request queuing and parallel processing. See Usage for more.
11
12
 
13
+
12
14
  ## Installation
13
15
 
14
16
  Add this line to your application's Gemfile:
@@ -23,6 +25,7 @@ Or install it yourself as:
23
25
 
24
26
  > gem install acfs
25
27
 
28
+
26
29
  ## Usage
27
30
 
28
31
  First you need to define your service(s):
@@ -144,6 +147,7 @@ Acfs has basic update support using `PUT` requests:
144
147
  @user.persisted? # => true
145
148
  ```
146
149
 
150
+
147
151
  ## Singleton resources
148
152
 
149
153
  Singletons can be used in Acfs by creating a new resource which inherits from `SingletonResource`:
@@ -182,6 +186,7 @@ my_single = Single.find name: 'Max'
182
186
  Acfs.run # sends GET request with param to /single?name=Max
183
187
  ```
184
188
 
189
+
185
190
  ## Resource Inheritance
186
191
 
187
192
  Acfs provides a resource inheritance similar to ActiveRecord Single Table Inheritance. If a
@@ -218,6 +223,7 @@ Acfs.run
218
223
  @computer[2].class # => Pc
219
224
  ```
220
225
 
226
+
221
227
  ## Stubbing
222
228
 
223
229
  You can stub resources in applications using an Acfs service client:
@@ -278,6 +284,7 @@ it 'should find user number one' do
278
284
  end
279
285
  ```
280
286
 
287
+
281
288
  ## Instrumentation
282
289
 
283
290
  Acfs supports [instrumentation via active support][1].
@@ -295,21 +302,6 @@ Read [official guide][2] to see to to subscribe.
295
302
  [1]: http://guides.rubyonrails.org/active_support_instrumentation.html
296
303
  [2]: http://guides.rubyonrails.org/active_support_instrumentation.html#subscribing-to-an-event
297
304
 
298
- ## Roadmap
299
-
300
- * Update
301
- * Better new? detection eg. storing ETag from request resources.
302
- * Use PATCH for with only changed attributes and `If-Unmodifed-Since`
303
- and `If-Match` header fields if resource was surly loaded from service
304
- and not created with an id (e.g `User.new id: 5, name: "john"`).
305
- * Conflict detection (ETag / If-Unmodified-Since)
306
- * High level features
307
- * Support for custom mime types on client and server side. (`application/vnd.myservice.user.v2+msgpack`)
308
- * Server side components
309
- * Reusing model definitions for generating responses?
310
- * Rails responders providing REST operations with integrated ETag,
311
- Modified Headers, conflict detection, ...
312
- * Documentation
313
305
 
314
306
  ## Contributing
315
307
 
@@ -321,14 +313,9 @@ Read [official guide][2] to see to to subscribe.
321
313
  7. Push to the branch (`git push origin my-new-feature`)
322
314
  8. Create new Pull Request
323
315
 
324
- ## Contributors
325
-
326
- * [Nicolas Fricke](https://github.com/nicolas-fricke)
327
- * [Tino Junge](https://github.com/tino-junge)
328
- * [Malte Swart](https://github.com/mswart)
329
316
 
330
317
  ## License
331
318
 
332
319
  MIT License
333
320
 
334
- Copyright (c) 2013 Jan Graichen. MIT license, see LICENSE for more details.
321
+ Copyright (c) 2013-2020 Jan Graichen. MIT license, see LICENSE for more details.
@@ -1,5 +1,6 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
3
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
5
  require 'acfs/version'
5
6
 
@@ -7,31 +8,29 @@ Gem::Specification.new do |spec|
7
8
  spec.name = 'acfs'
8
9
  spec.version = Acfs::VERSION
9
10
  spec.authors = ['Jan Graichen']
10
- spec.email = %w(jg@altimos.de)
11
- spec.description = 'API Client For Services'
12
- spec.summary = 'An abstract API base client for service oriented application.'
11
+ spec.email = %w[jgraichen@altimos.de]
13
12
  spec.homepage = 'https://github.com/jgraichen/acfs'
14
13
  spec.license = 'MIT'
14
+ spec.description = 'API Client For Services'
15
+ spec.summary = <<~SUMMARY.strip
16
+ An abstract API base client for service oriented application.
17
+ SUMMARY
18
+
19
+ spec.files = Dir['**/*'].grep(%r{
20
+ ^((bin|lib|test|spec|features)/|
21
+ .*\.gemspec|.*LICENSE.*|.*README.*|.*CHANGELOG.*)
22
+ }xi)
15
23
 
16
- spec.files = Dir['**/*'].grep(%r{^((bin|lib|test|spec|features)/|.*\.gemspec|.*LICENSE.*|.*README.*|.*CHANGELOG.*)})
17
24
  spec.executables = spec.files.grep(%r{^bin/}) {|f| File.basename(f) }
18
25
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
- spec.require_paths = %w(lib)
20
-
21
- spec.add_runtime_dependency 'activesupport', '>= 4.2'
22
- spec.add_runtime_dependency 'activemodel', '>= 4.2'
23
- spec.add_runtime_dependency 'actionpack', '>= 4.2'
24
- spec.add_runtime_dependency 'multi_json'
25
-
26
- # Bundle update w/o version resolves to 0.3.3 ...
27
- spec.add_runtime_dependency 'typhoeus', '~> 1.0'
26
+ spec.require_paths = %w[lib]
28
27
 
28
+ spec.add_runtime_dependency 'actionpack', '>= 5.2'
29
+ spec.add_runtime_dependency 'activemodel', '>= 5.2'
30
+ spec.add_runtime_dependency 'activesupport', '>= 5.2'
31
+ spec.add_runtime_dependency 'multi_json', '~> 1.0'
29
32
  spec.add_runtime_dependency 'rack'
33
+ spec.add_runtime_dependency 'typhoeus', '~> 1.0'
30
34
 
31
35
  spec.add_development_dependency 'bundler'
32
-
33
- if ENV['TRAVIS_BUILD_NUMBER'] && !ENV['TRAVIS_TAG']
34
- # Append travis build number for auto-releases
35
- spec.version = "#{spec.version}.1.b#{ENV['TRAVIS_BUILD_NUMBER']}"
36
- end
37
36
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'active_support'
2
4
  require 'active_support/core_ext/hash'
3
5
  require 'active_support/core_ext/class'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Acfs::Adapter
2
4
  # Base adapter handling operation queuing
3
5
  # and processing.
@@ -5,22 +7,18 @@ module Acfs::Adapter
5
7
  class Base
6
8
  # Start processing queued requests.
7
9
  #
8
- def start
9
- end
10
+ def start; end
10
11
 
11
12
  # Abort running and queued requests.
12
13
  #
13
- def abort
14
- end
14
+ def abort; end
15
15
 
16
16
  # Run request right now skipping queue.
17
17
  #
18
- def run(_)
19
- end
18
+ def run(_); end
20
19
 
21
20
  # Enqueue request to be run later.
22
21
  #
23
- def queue(_)
24
- end
22
+ def queue(_); end
25
23
  end
26
24
  end
@@ -1,17 +1,26 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'typhoeus'
2
4
 
3
5
  module Acfs
4
6
  module Adapter
7
+ DEFAULT_OPTIONS = {
8
+ tcp_keepalive: true,
9
+ tcp_keepidle: 5,
10
+ tcp_keepintvl: 5
11
+ }.freeze
12
+
5
13
  # Adapter for Typhoeus.
6
14
  #
7
15
  class Typhoeus < Base
8
- def initialize(**kwargs)
9
- @options = kwargs
16
+ def initialize(opts: {}, **kwargs)
17
+ @opts = DEFAULT_OPTIONS.merge(opts)
18
+ @kwargs = kwargs
10
19
  end
11
20
 
12
21
  def start
13
22
  hydra.run
14
- rescue
23
+ rescue StandardError
15
24
  @hydra = nil
16
25
  raise
17
26
  end
@@ -29,20 +38,30 @@ module Acfs
29
38
  protected
30
39
 
31
40
  def hydra
32
- @hydra ||= ::Typhoeus::Hydra.new(**@options)
41
+ @hydra ||= ::Typhoeus::Hydra.new(**@kwargs)
33
42
  end
34
43
 
35
44
  def convert_request(req)
36
- request = ::Typhoeus::Request.new req.url,
45
+ opts = {
37
46
  method: req.method,
38
47
  params: req.params,
39
48
  headers: req.headers.merge(
40
- 'Expect' => '',
49
+ 'Expect' => '',
41
50
  'Transfer-Encoding' => ''
42
51
  ),
43
52
  body: req.body
53
+ }
54
+
55
+ request = ::Typhoeus::Request.new(req.url, **@opts.merge(opts))
44
56
 
45
57
  request.on_complete do |response|
58
+ raise ::Acfs::TimeoutError.new(req) if response.timed_out?
59
+
60
+ if response.code.zero?
61
+ # Failed to get HTTP response
62
+ raise ::Acfs::RequestError.new(req, response.return_message)
63
+ end
64
+
46
65
  req.complete! convert_response(req, response)
47
66
  end
48
67
 
@@ -1,10 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'delegate'
2
4
 
3
5
  require 'acfs/resource/loadable'
4
6
  require 'acfs/collections/paginatable'
5
7
 
6
8
  module Acfs
7
- #
8
9
  class Collection < ::Delegator
9
10
  include Resource::Loadable
10
11
  include Acfs::Util::Callbacks
@@ -1,5 +1,6 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Acfs::Collections
2
- #
3
4
  module Paginatable
4
5
  extend ActiveSupport::Concern
5
6
 
@@ -67,8 +68,8 @@ module Acfs::Collections
67
68
  def setup_params(params)
68
69
  @current_page = begin
69
70
  Integer params.fetch(:page, 1)
70
- rescue ArgumentError
71
- params[:page]
71
+ rescue ArgumentError
72
+ params[:page]
72
73
  end
73
74
  end
74
75
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'uri'
2
4
  require 'yaml'
3
5
 
@@ -25,7 +27,7 @@ module Acfs
25
27
  # @return [undefined]
26
28
  #
27
29
  def configure(&block)
28
- if block.arity > 0
30
+ if block.arity.positive?
29
31
  block.call self
30
32
  else
31
33
  instance_eval(&block)
@@ -37,8 +39,12 @@ module Acfs
37
39
  # @overload locate(service, uri)
38
40
  # Configures URL where a service can be reached.
39
41
  #
40
- # @param [Symbol] service Service identity key for service that is reachable under given URL.
41
- # @param [String] uri URL where service is reachable. Will be passed to {URI.parse}.
42
+ # @param [Symbol] service
43
+ # Service identity key for service that is reachable under given URL.
44
+ #
45
+ # @param [String] uri
46
+ # URL where service is reachable. Will be passed to {URI.parse}.
47
+ #
42
48
  # @return [undefined]
43
49
  #
44
50
  # @overload locate(service)
@@ -64,7 +70,7 @@ module Acfs
64
70
  # @return [undefined]
65
71
  #
66
72
  def load(filename)
67
- config = YAML.load File.read filename
73
+ config = YAML.safe_load(File.read(filename), [], [], true)
68
74
  env = ENV['RACK_ENV'] || ENV['RAILS_ENV'] || 'development'
69
75
 
70
76
  config = config[env] if config.key? env
@@ -95,18 +101,19 @@ module Acfs
95
101
  # @return [Configuration]
96
102
  #
97
103
  def current
98
- @configuration ||= new
104
+ @current ||= new
99
105
  end
100
106
 
101
107
  # @api private
102
108
  #
103
- # Swap configuration object with given new one. Must be a {Configuration} object.
109
+ # Swap configuration object with given new one. Must be
110
+ # a {Configuration} object.
104
111
  #
105
112
  # @param [Configuration] configuration
106
113
  # @return [undefined]
107
114
  #
108
115
  def set(configuration)
109
- @configuration = configuration if configuration.is_a? Configuration
116
+ @current = configuration if configuration.is_a? Configuration
110
117
  end
111
118
  end
112
119
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Acfs
2
4
  # Acfs base error.
3
5
  #
@@ -10,6 +12,24 @@ module Acfs
10
12
 
11
13
  class UnsupportedOperation < StandardError; end
12
14
 
15
+ class RequestError < Error
16
+ attr_reader :request
17
+
18
+ def initialize(request, message)
19
+ @request = request
20
+
21
+ message = "#{message}: #{request.method.upcase} #{request.url}"
22
+
23
+ super message: message
24
+ end
25
+ end
26
+
27
+ class TimeoutError < RequestError
28
+ def initialize(request)
29
+ super(request, 'Timeout reached')
30
+ end
31
+ end
32
+
13
33
  # Response error containing the responsible response object.
14
34
  #
15
35
  class ErroneousResponse < Error
@@ -17,17 +37,15 @@ module Acfs
17
37
 
18
38
  def initialize(opts = {})
19
39
  @response = opts[:response]
20
- message = opts[:message]
21
- if response
22
- if message
23
- message << ':'
24
- else
25
- message = 'Received'
26
- end
27
- message << " #{response.code} for #{response.request.method.upcase} #{response.request.url} #{response.request.format}"
28
- else
29
- message ||= 'Received erroneous response'
30
- end
40
+
41
+ message = if response
42
+ (opts[:message] ? opts[:message] + ':' : 'Received') +
43
+ " #{response.code} for #{response.request.method.upcase}" \
44
+ " #{response.request.url} #{response.request.format}"
45
+ else
46
+ opts[:message] || 'Received erroneous response'
47
+ end
48
+
31
49
  super opts, message
32
50
  end
33
51
  end
@@ -41,17 +59,27 @@ module Acfs
41
59
  @stubs = opts.delete :stubs
42
60
  @operation = opts.delete :operation
43
61
 
44
- super opts, "Ambiguous stubs for #{operation.action} on #{operation.resource}.\n" +
45
- stubs.map {|s| " #{s.opts.pretty_inspect}" }.join
62
+ message = "Ambiguous stubs for #{operation.action} " \
63
+ "on #{operation.resource}.\n" +
64
+ stubs.map {|s| " #{s.opts.pretty_inspect}" }.join
65
+
66
+ super opts, message
46
67
  end
47
68
  end
48
69
 
49
- # Resource not found error raised on a 404 response
50
- #
51
- class ResourceNotFound < ErroneousResponse
52
- end
70
+ # 400
71
+ class BadRequest < ErroneousResponse; end
53
72
 
54
- #
73
+ # 401
74
+ class Unauthorized < ErroneousResponse; end
75
+
76
+ # 403
77
+ class Forbidden < ErroneousResponse; end
78
+
79
+ # 404
80
+ class ResourceNotFound < ErroneousResponse; end
81
+
82
+ # 422
55
83
  class InvalidResource < ErroneousResponse
56
84
  attr_reader :errors, :resource
57
85
 
@@ -71,6 +99,18 @@ module Acfs
71
99
  end
72
100
  end
73
101
 
102
+ # 500
103
+ class ServerError < ErroneousResponse; end
104
+
105
+ # 502
106
+ class BadGateway < ErroneousResponse; end
107
+
108
+ # 503
109
+ class ServiceUnavailable < ErroneousResponse; end
110
+
111
+ # 504
112
+ class GatewayTimeout < ErroneousResponse; end
113
+
74
114
  # A ResourceNotLoaded error will be thrown when calling some
75
115
  # modifing methods on not loaded resources as it is usally
76
116
  # unwanted to call e.g. `update_attributes` on a not loaded
@@ -97,7 +137,8 @@ module Acfs
97
137
  def initialize(opts = {})
98
138
  @base_class = opts.delete :base_class
99
139
  @type_name = opts.delete :type_name
100
- opts[:message] = "Received resource type `#{type_name}` is no subclass of #{base_class}"
140
+ opts[:message] = "Received resource type `#{type_name}` " \
141
+ "is no subclass of #{base_class}"
101
142
  super
102
143
  end
103
144
  end