lhs 6.2.0 → 6.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: caf31c361c00c17b98b17004fc597f5c89bfece9
4
- data.tar.gz: 54d832a896d135a0a5a7e84818cffb2aae0adcae
3
+ metadata.gz: 3e5f67d6a0394eaf9742357631505c14ecf0d308
4
+ data.tar.gz: 725d43ea3e43f8374e210b5d29a0e54fde5d4a11
5
5
  SHA512:
6
- metadata.gz: 416221fb3dc29dd39925000e38cb7a8549712eff5a33cb45a74d1a5f3d54a3060a8d384154d526a82bad2e42b59b8ba92d661c5dffac10cdbce5919669c4f082
7
- data.tar.gz: c07cf8c431c91fcb11fd17e852032693547526b1b018a527920d28dddac661ec3e576a034e6441092082a0ec0d0e36dba6658207b46262d70a87fffb6370e32e
6
+ metadata.gz: 5344e79fe480861ae6fe214f9c5fd7f19fb6bfaa754a99dc9afecb2de9efb636b1f80f3b76c7a6e0a23c1efa20e7264a884d8253a7c5c020c23e2b838cb637e8
7
+ data.tar.gz: b060a234369822f4dd32b945d576cf089e9e56352bd3ced2ee26aeb62c604f48e9febb72fb226c34ed723039ad012efe469ddabe71319264824b95a074726913
data/README.md CHANGED
@@ -124,6 +124,22 @@ records = Record.blue.available(true)
124
124
  The example would fetch records with the following parameters: `{color: blue, visible: true}`.
125
125
  ```
126
126
 
127
+ ## Error handling with chains
128
+
129
+ One benefit of chains is lazy evaluation. This means they get resolved when data is accessed. This makes it hard to catch errors with normal `rescue` blocks.
130
+
131
+ To simplify error handling with chains, you can also chain error handlers to be resolved, as part of the chain.
132
+
133
+ In case no matchin error handler is found the error gets re-raised.
134
+
135
+ ```ruby
136
+ record = Record.where(color: 'blue')
137
+ .handle(LHC::BadRequest, ->(error){ show_error })
138
+ .handle(LHC::Unauthorized, ->(error){ authorize })
139
+ ```
140
+
141
+ [List of possible error classes](https://github.com/local-ch/lhc/tree/master/lib/lhc/errors)
142
+
127
143
  ## Find single records
128
144
 
129
145
  `find` finds a unique record by uniqe identifier (usualy id).
@@ -30,6 +30,10 @@ class LHS::Record
30
30
  def limit(argument = nil)
31
31
  Chain.new(self, Pagination.new(per: argument))
32
32
  end
33
+
34
+ def handle(error_class, handler)
35
+ Chain.new(self, ErrorHandling.new(error_class => handler))
36
+ end
33
37
  end
34
38
 
35
39
  # Link: A part of a chain
@@ -59,6 +63,19 @@ class LHS::Record
59
63
  class Pagination < Link
60
64
  end
61
65
 
66
+ # ErrorHandling: Catch and resolve errors when resolving the chain
67
+ class ErrorHandling < Link
68
+ delegate :call, to: :handler
69
+
70
+ def handler
71
+ @hash.values.first
72
+ end
73
+
74
+ def class
75
+ @hash.keys.first
76
+ end
77
+ end
78
+
62
79
  # A sequence of links
63
80
  class Chain
64
81
 
@@ -140,6 +157,10 @@ class LHS::Record
140
157
  push Pagination.new(per: argument)
141
158
  end
142
159
 
160
+ def handle(error_class, handler)
161
+ push ErrorHandling.new(error_class => handler)
162
+ end
163
+
143
164
  def find(args)
144
165
  @record_class.find(args, chain_options)
145
166
  end
@@ -181,6 +202,7 @@ class LHS::Record
181
202
  @record_class.request(
182
203
  chain_options
183
204
  .merge(params: chain_parameters.merge(chain_pagination))
205
+ .merge(error_handling: chain_error_handling)
184
206
  )
185
207
  )
186
208
  end
@@ -201,6 +223,10 @@ class LHS::Record
201
223
  merge_links _links.select { |link| link.is_a? Option }
202
224
  end
203
225
 
226
+ def chain_error_handling
227
+ _links.select { |link| link.is_a? ErrorHandling }
228
+ end
229
+
204
230
  def chain_pagination
205
231
  resolve_pagination _links.select { |link| link.is_a? Pagination }
206
232
  end
@@ -243,10 +243,25 @@ class LHS::Record
243
243
  options ||= {}
244
244
  options = options.dup
245
245
  endpoint = find_endpoint(options[:params])
246
- response = LHC.request(process_options(options, endpoint))
247
- data = LHS::Data.new(response.body, nil, self, response.request, endpoint)
248
- handle_includes(including, data, referencing) if including
249
- data
246
+ error_handling = options.delete(:error_handling)
247
+ begin
248
+ response = LHC.request(process_options(options, endpoint))
249
+ data = LHS::Data.new(response.body, nil, self, response.request, endpoint)
250
+ handle_includes(including, data, referencing) if including
251
+ data
252
+ rescue => error
253
+ handle_error(error, error_handling)
254
+ nil
255
+ end
256
+ end
257
+
258
+ def handle_error(error, error_handling)
259
+ error_handlers = (error_handling || []).select { |error_handler| error.is_a? error_handler.class }
260
+ if error_handlers.any?
261
+ error_handlers.each { |handler| handler.call(error) }
262
+ else
263
+ fail error
264
+ end
250
265
  end
251
266
 
252
267
  def url_option_for(item, key = nil)
data/lib/lhs/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module LHS
2
- VERSION = "6.2.0"
2
+ VERSION = "6.3.0"
3
3
  end
@@ -0,0 +1,38 @@
1
+ require 'rails_helper'
2
+
3
+ describe LHS::Record do
4
+ let(:handler) { spy('handler') }
5
+
6
+ before(:each) do
7
+ class Record < LHS::Record
8
+ endpoint 'http://local.ch/v2/records'
9
+ end
10
+ stub_request(:get, "http://local.ch/v2/records?color=blue")
11
+ .to_return(status: 400)
12
+ end
13
+
14
+ it 'allows to chain error handling' do
15
+ expect {
16
+ Record.where(color: 'blue').handle(LHC::Error, ->(_error) { handler.handle }).first
17
+ }.not_to raise_error
18
+ expect(handler).to have_received(:handle)
19
+ end
20
+
21
+ it 'reraises in case chained error is not matched' do
22
+ expect {
23
+ Record.where(color: 'blue').handle(LHC::Conflict, ->(_error) { handler.handle }).first
24
+ }.to raise_error(LHC::Error)
25
+ expect(handler).not_to have_received(:handle)
26
+ end
27
+
28
+ it 'calls all the handlers' do
29
+ expect {
30
+ Record.where(color: 'blue')
31
+ .handle(LHC::Error, ->(_error) { handler.handle_1 })
32
+ .handle(LHC::Error, ->(_error) { handler.handle_2 })
33
+ .first
34
+ }.not_to raise_error
35
+ expect(handler).to have_received(:handle_1)
36
+ expect(handler).to have_received(:handle_2)
37
+ end
38
+ end
@@ -149,25 +149,20 @@ describe LHS::Record do
149
149
  }.to_json)
150
150
  end
151
151
 
152
+ let(:interceptor) { spy('interceptor') }
153
+
152
154
  before(:each) do
153
155
  class Entry < LHS::Record
154
156
  endpoint ':datastore/local-entries/:id'
155
157
  end
156
- class SomeInterceptor < LHC::Interceptor; end
157
- LHC.config.interceptors = [SomeInterceptor]
158
+ LHC.config.interceptors = [interceptor]
158
159
  end
159
160
 
160
161
  it 'uses interceptors for included links from known services' do
161
- # rubocop:disable RSpec/InstanceVariable
162
162
  stub_feedback_request
163
163
  stub_entry_request
164
-
165
- @called = 0
166
- allow_any_instance_of(SomeInterceptor).to receive(:before_request) { @called += 1 }
167
-
168
164
  expect(Feedback.includes(:entry).where.first.entry.name).to eq 'Casa Ferlin'
169
- expect(@called).to eq 2
170
- # rubocop:enable RSpec/InstanceVariable
165
+ expect(interceptor).to have_received(:before_request).twice
171
166
  end
172
167
  end
173
168
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lhs
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.2.0
4
+ version: 6.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - https://github.com/local-ch/lhs/graphs/contributors
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-03 00:00:00.000000000 Z
11
+ date: 2016-08-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: lhc
@@ -287,6 +287,7 @@ files:
287
287
  - spec/record/all_spec.rb
288
288
  - spec/record/build_spec.rb
289
289
  - spec/record/cast_nested_data_spec.rb
290
+ - spec/record/chain_error_handling_spec.rb
290
291
  - spec/record/create_spec.rb
291
292
  - spec/record/creation_failed_spec.rb
292
293
  - spec/record/definitions_spec.rb
@@ -431,6 +432,7 @@ test_files:
431
432
  - spec/record/all_spec.rb
432
433
  - spec/record/build_spec.rb
433
434
  - spec/record/cast_nested_data_spec.rb
435
+ - spec/record/chain_error_handling_spec.rb
434
436
  - spec/record/create_spec.rb
435
437
  - spec/record/creation_failed_spec.rb
436
438
  - spec/record/definitions_spec.rb