lhs 6.2.0 → 6.3.0

Sign up to get free protection for your applications and to get access to all the features.
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