pipe-ruby 0.3.1 → 1.0.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: d0eca86ffad3466f3843db7cb3013985bfc1c3bf
4
- data.tar.gz: df2cd7013334b5abce3608c1c85bcd4ca261201a
3
+ metadata.gz: 195a31eb3c9e9ddb6f80a553703cf0501c50b72f
4
+ data.tar.gz: abfdff691c25899d33931d210180c423a612550f
5
5
  SHA512:
6
- metadata.gz: 918395735261b1110693cfa0c08d933e5c7c8ea5e0a73597a3d067a5fc3b29044f36a47b608dfb5a0c911f9df1f3711ff50fbf765bb6a960b91bff22670a30f8
7
- data.tar.gz: 9338db4f769305be5ad63474cca4e4e2ef2fcfebee1f8eb0ade7a2231f992beebfe6e92d842e31be5e823c1d208ba109c911cd72c63f944048214b785d342bf8
6
+ metadata.gz: 6e245799adc6c83fd32ac002b45fafd1475b03beec178e0b99871f4dd891185c912d0bcc7f4dd2bf9f7e2e87777b55a8bbeafbc496a8062b113eb71c86aebed3
7
+ data.tar.gz: 84c1fe2750d276eaf7d673f2040e018102f31c3de8f98ceb7a83c3161e5b46f832241dc58fa4fdac5b850ea33617d5709fbdb5b9ce68cbd278f17e75fc283686
@@ -0,0 +1,4 @@
1
+ # Change Log
2
+
3
+ ## 1.0.0 (2020-02-25)
4
+ - remove pipe-ruby error handling
data/README.md CHANGED
@@ -55,15 +55,9 @@ configurable options. Here they are with their defaults:
55
55
 
56
56
  ```ruby
57
57
  Pipe::Config.new(
58
- :error_handlers => [], # an array of procs to be called when an error
59
- # occurs
60
- :raise_on_error => true, # tells Pipe to re-raise errors which occur
61
- :return_on_error => :subject, # when an error happens and raise error is false
62
- # returns the current value of subject defaultly;
63
- # if callable, will return the result of the call
64
- # if not callable, will return the value
65
58
  :skip_on => false, # a truthy value or proc which tells pipe to skip
66
59
  # the next method in the `through` array
60
+
67
61
  :stop_on => false # a truthy value or proc which tells pipe to stop
68
62
  # processing and return the current value
69
63
  )
@@ -82,7 +76,7 @@ class MyClass
82
76
  include Pipe
83
77
 
84
78
  def my_method
85
- config = Pipe::Config.new(:raise_on_error => false)
79
+ config = Pipe::Config.new(:skip_on => false)
86
80
  subject = Object.new
87
81
 
88
82
  pipe(subject, :config => config, :through => [
@@ -101,7 +95,7 @@ class MyClass
101
95
  include Pipe
102
96
 
103
97
  def pipe_config
104
- Pipe::Config.new(:raise_on_error => false)
98
+ Pipe::Config.new(:skip_on => false)
105
99
  end
106
100
 
107
101
  # ...
@@ -115,45 +109,13 @@ class MyClass
115
109
  include Pipe
116
110
 
117
111
  def initialize
118
- @pipe_config = Pipe::Config.new(:raise_on_error => false)
112
+ @pipe_config = Pipe::Config.new(:skip_on => false)
119
113
  end
120
114
 
121
115
  # ...
122
116
  end
123
117
  ```
124
118
 
125
- ## Error Handling
126
-
127
- As we implemented different versions of `pipe` across our infrastructure, we
128
- came across several different error handling needs.
129
-
130
- - logging errors that occur in methods called by pipe without raising them
131
- - catching and re-raising errors with additional information so we can still
132
- see the real backtrace while also gaining insight into which subject and
133
- method combination triggered the error
134
- - easily seeing which area of the pipe stack we were in when an error occurred
135
-
136
- The first layer of error handling is the `error_handlers` attribute in
137
- `Pipe::Config`. Each proc in this array will be called with two arguments,
138
- the actual error object and a context hash containing the method and subject
139
- when the error occurred. If an error occurs within one of these handlers it
140
- will be re-raised inside the `Pipe::HandlerError` namespace, meaning a
141
- `NameError` becomes a `Pipe::HandlerError::NameError`. We also postpend the
142
- current method, current subject and original error class to the message.
143
-
144
- NOTE: `Pipe::Config#error_handler` takes a block and adds it to the existing
145
- error handlers.
146
-
147
- We have two other namespaces, `Pipe::ReducerError`, which is used when an error
148
- occurs inside during `pipe` execution and `Pipe::IteratorError` for errors which
149
- occur inside of `pipe_each` execution.
150
-
151
- Whenever an error occurs in execution (but not in error handler processing), the
152
- response of `Pipe::Config#raise_on_error?` is checked. If this method returns
153
- `true`, the error will be re-raised inside of the appropriate namespace. If it
154
- returns `false`, the current value of `subject` will be returned and execution
155
- stopped.
156
-
157
119
  ## Skipping / Stopping Execution
158
120
 
159
121
  At the beginning of each iteration, `Pipe::Config#stop_on` is called. If it
@@ -1,6 +1,5 @@
1
1
  require "pipe/ext/string"
2
2
  require "pipe/config"
3
- require "pipe/error"
4
3
  require "pipe/iterator"
5
4
  require "pipe/reducer"
6
5
 
@@ -1,34 +1,19 @@
1
1
  module Pipe
2
2
  class Config
3
- attr_accessor :raise_on_error
4
- attr_reader :error_handlers, :return_on_error, :skip_on, :stop_on
3
+ attr_reader :skip_on, :stop_on
5
4
 
6
5
  def initialize(
7
- error_handlers: [],
8
- raise_on_error: true,
9
- return_on_error: :subject,
10
6
  skip_on: false,
11
7
  stop_on: false
12
8
  )
13
- @error_handlers = error_handlers
14
- @raise_on_error = raise_on_error
15
- @return_on_error = return_on_error
16
9
  self.skip_on = skip_on
17
10
  self.stop_on = stop_on
18
11
  end
19
12
 
20
- def error_handler(&block)
21
- error_handlers << block if block_given?
22
- end
23
-
24
13
  def break?(*args)
25
14
  stop_on.call(*args) ? true : false
26
15
  end
27
16
 
28
- def raise_on_error?
29
- raise_on_error ? true : false
30
- end
31
-
32
17
  def skip?(*args)
33
18
  skip_on.call(*args) ? true : false
34
19
  end
@@ -9,33 +9,18 @@ module Pipe
9
9
 
10
10
  def iterate
11
11
  subjects.map { |subject|
12
- begin
13
- Reducer.new(
14
- config: config,
15
- context: context,
16
- subject: subject,
17
- through: through
18
- ).reduce
19
- rescue => e
20
- handle_error(:error => e, :subject => subject)
21
- subject
22
- end
12
+ Reducer.new(
13
+ config: config,
14
+ context: context,
15
+ subject: subject,
16
+ through: through
17
+ ).reduce
23
18
  }
24
19
  end
25
20
 
26
21
  private
27
-
28
22
  attr_accessor :config, :context, :subjects, :through
29
23
 
30
- def handle_error(error:, subject:)
31
- if config.raise_on_error?
32
- Error.process(
33
- :data => { :subject => subject },
34
- :error => error,
35
- :namespace => IterationError,
36
- )
37
- end
38
- end
39
24
  end
40
25
  end
41
26
 
@@ -9,15 +9,8 @@ module Pipe
9
9
 
10
10
  def reduce
11
11
  through.reduce(subject) { |subj, method|
12
- begin
13
- break subj if config.break?(subj, method, through)
14
-
15
- process(subj, method)
16
- rescue => e
17
- payload = {:error => e, :method => method, :subject => subj}
18
- handle_error(payload)
19
- break error_response(payload)
20
- end
12
+ break subj if config.break?(subj, method, through)
13
+ process(subj, method)
21
14
  }
22
15
  end
23
16
 
@@ -25,32 +18,6 @@ module Pipe
25
18
 
26
19
  attr_accessor :config, :context, :subject, :through
27
20
 
28
- def error_response(error:, method:, subject:)
29
- if config.return_on_error == :subject
30
- subject
31
- elsif config.return_on_error.respond_to?(:call)
32
- config.return_on_error.call(subject, method, error)
33
- else
34
- config.return_on_error
35
- end
36
- end
37
-
38
- def handle_error(error:, method:, subject:)
39
- process_error_handlers(
40
- :error => error,
41
- :method => method,
42
- :subject => subject
43
- )
44
-
45
- if config.raise_on_error?
46
- Error.process(
47
- :data => { :method => method, :subject => subject },
48
- :error => error,
49
- :namespace => ReducerError,
50
- )
51
- end
52
- end
53
-
54
21
  def process(subj, method)
55
22
  if config.skip?(subj, method, through)
56
23
  subj
@@ -58,20 +25,6 @@ module Pipe
58
25
  context.send(method, subj)
59
26
  end
60
27
  end
61
-
62
- def process_error_handlers(error:, method:, subject:)
63
- data = { method: method, subject: subject }
64
-
65
- begin
66
- config.error_handlers.each { |handler| handler.call(error, data) }
67
- rescue => e
68
- Error.process(
69
- :data => data,
70
- :error => e,
71
- :namespace => HandlerError,
72
- )
73
- end
74
- end
75
28
  end
76
29
  end
77
30
 
@@ -1,3 +1,3 @@
1
1
  module Pipe
2
- VERSION = "0.3.1"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -6,8 +6,8 @@ require 'pipe/version'
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "pipe-ruby"
8
8
  spec.version = Pipe::VERSION
9
- spec.authors = ["Dan Matthews"]
10
- spec.email = ["oss@teamsnap.com"]
9
+ spec.authors = ["Dan Matthews, Paul Hanyzewski"]
10
+ spec.email = ["devs@teamsnap.com"]
11
11
  spec.summary = %q{Ruby implementation of the UNIX pipe}
12
12
  spec.description = %q{}
13
13
  spec.homepage = ""
@@ -2,18 +2,6 @@ require "spec_helper"
2
2
 
3
3
  describe Pipe::Config do
4
4
  describe "defaults" do
5
- it "sets error handlers to a blank array" do
6
- expect(Pipe::Config.new.error_handlers).to eq([])
7
- end
8
-
9
- it "sets raise_on_error to true" do
10
- expect(Pipe::Config.new.raise_on_error).to eq(true)
11
- end
12
-
13
- it "sets return_on_error to :subject" do
14
- expect(Pipe::Config.new.return_on_error).to eq(:subject)
15
- end
16
-
17
5
  it "sets skip_on to a proc which returns false" do
18
6
  expect(Pipe::Config.new.skip_on.call).to eq(false)
19
7
  end
@@ -23,21 +11,6 @@ describe Pipe::Config do
23
11
  end
24
12
  end
25
13
 
26
- describe "#error_handler" do
27
- context "when passed a block" do
28
- it "adds the block to the error_handlers array" do
29
- config = Pipe::Config.new
30
- block = proc { "error handler" }
31
-
32
- expect{ config.error_handler(&block) }
33
- .to change{ config.error_handlers.size }
34
- .by(1)
35
-
36
- expect(config.error_handlers.last).to eq(block)
37
- end
38
- end
39
- end
40
-
41
14
  describe "#break?" do
42
15
  it "returns a truthy version of the result of calling stop_on" do
43
16
  config = Pipe::Config.new(:stop_on => proc { 1 })
@@ -57,18 +30,6 @@ describe Pipe::Config do
57
30
  end
58
31
  end
59
32
 
60
- describe "#raise_on_error?" do
61
- it "returns a truthy version of raise_on_error" do
62
- config = Pipe::Config.new
63
- config.raise_on_error = nil
64
- expect(config.raise_on_error?).to eq(false)
65
- config.raise_on_error = true
66
- expect(config.raise_on_error?).to eq(true)
67
- config.raise_on_error = "yes"
68
- expect(config.raise_on_error?).to eq(true)
69
- end
70
- end
71
-
72
33
  describe "#skip?" do
73
34
  it "returns a truthy version of the result of calling skip_on" do
74
35
  config = Pipe::Config.new(:skip_on => proc { 42 })
@@ -27,60 +27,20 @@ describe Pipe::Iterator do
27
27
  end
28
28
 
29
29
  describe "when an error occurs" do
30
- describe "and Config#raise_on_error is set to false" do
31
- it "does not raise" do
32
- dub = Object.new
33
- dub.singleton_class.send(:define_method, :reduce) do
34
- raise StandardError, "fail"
35
- end
36
- iterator = Pipe::Iterator.new(
37
- :config => Pipe::Config.new(:raise_on_error => false),
38
- :context => Object.new,
39
- :subjects => [Object.new],
40
- :through => [:to_s]
41
- )
42
- expect(Pipe::Reducer).to receive(:new).and_return(dub)
43
-
44
- expect{ iterator.iterate }.to_not raise_error
45
- end
46
-
47
- it "returns an array of the original items" do
48
- dub = Object.new
49
- dub.singleton_class.send(:define_method, :reduce) do
50
- raise StandardError, "fail"
51
- end
52
- subjects = [Object.new, Object.new]
53
- iterator = Pipe::Iterator.new(
54
- :config => Pipe::Config.new(:raise_on_error => false),
55
- :context => Object.new,
56
- :subjects => subjects,
57
- :through => [:to_s]
58
- )
59
- expect(Pipe::Reducer)
60
- .to receive(:new)
61
- .and_return(dub)
62
- .exactly(2).times
63
-
64
- expect(iterator.iterate).to eq(subjects)
65
- end
66
- end
67
-
68
- describe "and Config#raise_on_error is set to true" do
69
- it "raises" do
70
- dub = Object.new
71
- dub.singleton_class.send(:define_method, :reduce) do
72
- raise StandardError, "fail"
73
- end
74
- iterator = Pipe::Iterator.new(
75
- :config => Pipe::Config.new(:raise_on_error => true),
76
- :context => Object.new,
77
- :subjects => [Object.new],
78
- :through => [:to_s]
79
- )
80
- expect(Pipe::Reducer).to receive(:new).and_return(dub)
81
-
82
- expect{ iterator.iterate }.to raise_error
30
+ it "raises an error" do
31
+ dub = Object.new
32
+ dub.singleton_class.send(:define_method, :reduce) do
33
+ raise StandardError, "fail"
83
34
  end
35
+ iterator = Pipe::Iterator.new(
36
+ :config => Pipe::Config.new(),
37
+ :context => Object.new,
38
+ :subjects => [Object.new],
39
+ :through => [:to_s]
40
+ )
41
+ expect(Pipe::Reducer).to receive(:new).and_return(dub)
42
+
43
+ expect{ iterator.iterate }.to raise_error
84
44
  end
85
45
  end
86
46
  end
@@ -112,120 +112,24 @@ describe Pipe::Reducer do
112
112
  expect(reducer.reduce).to eq(subject.to_s.to_sym)
113
113
  end
114
114
 
115
- it "calls the error handlers when a raise occurs" do
116
- handler1 = Proc.new {}
117
- handler2 = Proc.new {}
118
- config = Pipe::Config.new(:error_handlers => [handler1, handler2])
119
- context = Class.new do
120
- ExpectedError = Class.new(StandardError)
121
-
122
- def bomb(subject)
123
- raise ExpectedError, "BOOM!"
124
- end
125
- end.new
115
+ it "does not modify errors" do
116
+ config = Pipe::Config.new()
117
+ OneMoreError = Class.new(StandardError)
126
118
 
127
- expect(handler1).to receive(:call)
128
- expect(handler2).to receive(:call)
129
-
130
- expect{
131
- Pipe::Reducer.new(
132
- :config => config,
133
- :context => context,
134
- :subject => Object.new,
135
- :through => [:bomb]
136
- ).reduce
137
- }.to raise_error
138
- end
139
-
140
- it "honors Config#raise_on_error" do
141
- config = Pipe::Config.new(:raise_on_error => false)
142
119
  context = Class.new do
143
- AnotherExpectedError = Class.new(StandardError)
144
-
145
- def bomb(subject)
146
- raise AnotherExpectedError, "BOOM!"
147
- end
148
- end.new
149
-
150
- expect{
151
- Pipe::Reducer.new(
152
- :config => config,
153
- :context => context,
154
- :subject => Object.new,
155
- :through => [:bomb]
156
- ).reduce
157
- }.to_not raise_error
158
- end
159
-
160
- it "honors Config#return_on_error :subject default" do
161
- config = Pipe::Config.new(:raise_on_error => false)
162
- context = Class.new do
163
- AndAnotherExpectedError = Class.new(StandardError)
164
-
165
- def bomb(subject)
166
- raise AndAnotherExpectedError, "BOOM!"
167
- end
168
- end.new
169
- subject = Object.new
170
-
171
- expect(
172
- Pipe::Reducer.new(
173
- :config => config,
174
- :context => context,
175
- :subject => subject,
176
- :through => [:bomb]
177
- ).reduce
178
- ).to eq(subject)
179
- end
180
-
181
- it "honors Config#return_on_error callable objects" do
182
- subject = Object.new
183
- config = Pipe::Config.new(
184
- :raise_on_error => false,
185
- :return_on_error => proc { |subj, method, e|
186
- [subj, method, e.class, e.to_s, :hello]
187
- }
188
- )
189
- context = Class.new do
190
- YetAnotherExpectedError = Class.new(StandardError)
191
-
192
- def bomb(subject)
193
- raise YetAnotherExpectedError, "BOOM!"
194
- end
195
- end.new
196
- expected = [subject, :bomb, YetAnotherExpectedError, "BOOM!", :hello]
197
-
198
- expect(
199
- Pipe::Reducer.new(
200
- :config => config,
201
- :context => context,
202
- :subject => subject,
203
- :through => [:bomb]
204
- ).reduce
205
- ).to eq(expected)
206
- end
207
-
208
- it "returns Config#return_on_error when not callable" do
209
- config = Pipe::Config.new(
210
- :raise_on_error => false,
211
- :return_on_error => :error
212
- )
213
- context = Class.new do
214
- OneMoreError = Class.new(StandardError)
215
-
216
120
  def bomb(subject)
217
121
  raise OneMoreError, "BOOM!"
218
122
  end
219
123
  end.new
220
124
 
221
- expect(
125
+ expect{
222
126
  Pipe::Reducer.new(
223
127
  :config => config,
224
128
  :context => context,
225
129
  :subject => Object.new,
226
130
  :through => [:bomb]
227
131
  ).reduce
228
- ).to eq(:error)
132
+ }.to raise_error(OneMoreError)
229
133
  end
230
134
  end
231
135
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pipe-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
- - Dan Matthews
7
+ - Dan Matthews, Paul Hanyzewski
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-12 00:00:00.000000000 Z
11
+ date: 2020-02-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -68,20 +68,20 @@ dependencies:
68
68
  version: '0'
69
69
  description: ''
70
70
  email:
71
- - oss@teamsnap.com
71
+ - devs@teamsnap.com
72
72
  executables: []
73
73
  extensions: []
74
74
  extra_rdoc_files: []
75
75
  files:
76
76
  - ".gitignore"
77
77
  - ".rspec"
78
+ - CHANGELOG.md
78
79
  - Gemfile
79
80
  - LICENSE.txt
80
81
  - README.md
81
82
  - Rakefile
82
83
  - lib/pipe.rb
83
84
  - lib/pipe/config.rb
84
- - lib/pipe/error.rb
85
85
  - lib/pipe/ext/inflection.rb
86
86
  - lib/pipe/ext/string.rb
87
87
  - lib/pipe/iterator.rb
@@ -89,7 +89,6 @@ files:
89
89
  - lib/pipe/version.rb
90
90
  - pipe-ruby.gemspec
91
91
  - spec/pipe/config_spec.rb
92
- - spec/pipe/error_spec.rb
93
92
  - spec/pipe/iterator_spec.rb
94
93
  - spec/pipe/reducer_spec.rb
95
94
  - spec/spec_helper.rb
@@ -113,13 +112,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
113
112
  version: '0'
114
113
  requirements: []
115
114
  rubyforge_project:
116
- rubygems_version: 2.2.2
115
+ rubygems_version: 2.5.2.3
117
116
  signing_key:
118
117
  specification_version: 4
119
118
  summary: Ruby implementation of the UNIX pipe
120
119
  test_files:
121
120
  - spec/pipe/config_spec.rb
122
- - spec/pipe/error_spec.rb
123
121
  - spec/pipe/iterator_spec.rb
124
122
  - spec/pipe/reducer_spec.rb
125
123
  - spec/spec_helper.rb
@@ -1,38 +0,0 @@
1
- module Pipe
2
- HandlerError = Module.new
3
- IterationError = Module.new
4
- ReducerError = Module.new
5
-
6
- class Error
7
- def self.process(data: {}, error:, namespace:)
8
- new(error).rewrite_as(:namespace => namespace, :data => data)
9
- end
10
-
11
- def initialize(e)
12
- @e = e
13
- end
14
-
15
- def rewrite_as(data: {}, namespace:)
16
- subclass = find_or_create_subclass(namespace)
17
- raise subclass, "#{e} [#{data}, #{e.class}]", e.backtrace
18
- end
19
-
20
- private
21
-
22
- attr_reader :e
23
-
24
- def find_or_create_subclass(namespace)
25
- part = e.class.name.split("::").last
26
- subclass_name = "#{namespace.name}::#{part}"
27
-
28
- begin
29
- subclass_name.constantize
30
- rescue NameError
31
- eval "#{subclass_name} = Class.new(StandardError)"
32
- end
33
-
34
- subclass_name.constantize
35
- end
36
- end
37
- end
38
-
@@ -1,54 +0,0 @@
1
- require "spec_helper"
2
-
3
- Namespace = Module.new
4
-
5
- describe Pipe::Error do
6
- describe ".process" do
7
- it "re-renders the error under the namespace passed" do
8
- begin
9
- begin
10
- not_a_method(:boom)
11
- rescue => e
12
- Pipe::Error.process(:error => e, :namespace => Namespace)
13
- end
14
- rescue => e
15
- @err = e
16
- end
17
-
18
- expect(@err.class.name).to eq("Namespace::NoMethodError")
19
- end
20
-
21
- it "adds the original error class to the message" do
22
- begin
23
- begin
24
- not_a_method(:boom)
25
- rescue => e
26
- Pipe::Error.process(:error => e, :namespace => Namespace)
27
- end
28
- rescue => e
29
- @err = e
30
- end
31
-
32
- expect(@err.message).to match(Regexp.new("NoMethodError"))
33
- end
34
-
35
- it "adds the data passed to the message" do
36
- data = {:one => 1, :two => 2}
37
- begin
38
- begin
39
- not_a_method(:boom)
40
- rescue => e
41
- Pipe::Error.process(
42
- :data => data,
43
- :error => e,
44
- :namespace => Namespace
45
- )
46
- end
47
- rescue => e
48
- @err = e
49
- end
50
-
51
- expect(@err.message).to match(Regexp.new("#{data}"))
52
- end
53
- end
54
- end