enhanced_errors 3.0.1 → 3.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardoc/checksums +2 -2
- data/.yardoc/object_types +0 -0
- data/.yardoc/objects/root.dat +0 -0
- data/doc/Context.html +1 -1
- data/doc/Enhanced/Colors.html +1 -1
- data/doc/Enhanced.html +1 -1
- data/doc/EnhancedErrors.html +454 -899
- data/doc/EnhancedExceptionContext.html +1 -1
- data/doc/Exception.html +1 -1
- data/doc/ExceptionBindingInfos.html +1 -1
- data/doc/Minitest.html +4 -2
- data/doc/_index.html +1 -1
- data/doc/file.README.html +1 -1
- data/doc/index.html +1 -1
- data/doc/method_list.html +25 -81
- data/doc/top-level-namespace.html +4 -6
- data/enhanced_errors.gemspec +1 -1
- data/lib/enhanced/minitest_patch.rb +1 -0
- data/lib/enhanced_errors.rb +49 -106
- metadata +3 -3
data/lib/enhanced_errors.rb
CHANGED
@@ -7,11 +7,9 @@ require 'monitor'
|
|
7
7
|
require_relative 'enhanced/colors'
|
8
8
|
require_relative 'enhanced/exception'
|
9
9
|
|
10
|
-
IGNORED_EXCEPTIONS = %w[SystemExit NoMemoryError SignalException Interrupt
|
11
|
-
|
12
|
-
|
13
|
-
RSpec::Matchers::BuiltIn::RaiseError
|
14
|
-
SystemStackError Psych::BadAlias]
|
10
|
+
IGNORED_EXCEPTIONS = %w[SystemExit NoMemoryError SignalException Interrupt ScriptError LoadError
|
11
|
+
NotImplementedError SyntaxError RSpec::Expectations::ExpectationNotMetError
|
12
|
+
RSpec::Matchers::BuiltIn::RaiseError SystemStackError Psych::BadAlias]
|
15
13
|
|
16
14
|
class EnhancedErrors
|
17
15
|
extend ::Enhanced
|
@@ -24,8 +22,8 @@ class EnhancedErrors
|
|
24
22
|
attr_accessor :enabled, :config_block, :on_capture_hook, :eligible_for_capture, :exception_trace, :override_messages
|
25
23
|
|
26
24
|
GEMS_REGEX = %r{[\/\\]gems[\/\\]}
|
27
|
-
DEFAULT_MAX_CAPTURE_LENGTH =
|
28
|
-
MAX_BINDING_INFOS =
|
25
|
+
DEFAULT_MAX_CAPTURE_LENGTH = 2200
|
26
|
+
MAX_BINDING_INFOS = 2
|
29
27
|
|
30
28
|
RSPEC_SKIP_LIST = [
|
31
29
|
:@__inspect_output,
|
@@ -86,6 +84,16 @@ class EnhancedErrors
|
|
86
84
|
|
87
85
|
RSPEC_HANDLER_NAMES = ['RSpec::Expectations::PositiveExpectationHandler', 'RSpec::Expectations::NegativeExpectationHandler']
|
88
86
|
|
87
|
+
CI_ENV_VARS = {
|
88
|
+
'CI' => ENV['CI'],
|
89
|
+
'JENKINS' => ENV['JENKINS'],
|
90
|
+
'GITHUB_ACTIONS' => ENV['GITHUB_ACTIONS'],
|
91
|
+
'CIRCLECI' => ENV['CIRCLECI'],
|
92
|
+
'TRAVIS' => ENV['TRAVIS'],
|
93
|
+
'APPVEYOR' => ENV['APPVEYOR'],
|
94
|
+
'GITLAB_CI' => ENV['GITLAB_CI']
|
95
|
+
}
|
96
|
+
|
89
97
|
@enabled = nil
|
90
98
|
@max_capture_length = nil
|
91
99
|
@capture_rescue = nil
|
@@ -98,10 +106,6 @@ class EnhancedErrors
|
|
98
106
|
@exception_trace = nil
|
99
107
|
@override_messages = nil
|
100
108
|
|
101
|
-
# Default values
|
102
|
-
@max_capture_events = -1 # -1 means no limit
|
103
|
-
@capture_events_count = 0
|
104
|
-
|
105
109
|
# Thread-safe getters and setters
|
106
110
|
def enabled=(val)
|
107
111
|
mutex.synchronize { @enabled = val }
|
@@ -119,19 +123,6 @@ class EnhancedErrors
|
|
119
123
|
mutex.synchronize { @capture_rescue }
|
120
124
|
end
|
121
125
|
|
122
|
-
def capture_events_count
|
123
|
-
mutex.synchronize { @capture_events_count || 0 }
|
124
|
-
end
|
125
|
-
|
126
|
-
def capture_events_count=(val)
|
127
|
-
mutex.synchronize { @capture_events_count = val }
|
128
|
-
end
|
129
|
-
|
130
|
-
def max_capture_events
|
131
|
-
mutex.synchronize { @max_capture_events || -1 }
|
132
|
-
end
|
133
|
-
|
134
|
-
|
135
126
|
def max_capture_length
|
136
127
|
mutex.synchronize { @max_capture_length || DEFAULT_MAX_CAPTURE_LENGTH }
|
137
128
|
end
|
@@ -140,18 +131,6 @@ class EnhancedErrors
|
|
140
131
|
mutex.synchronize { @max_capture_length = value }
|
141
132
|
end
|
142
133
|
|
143
|
-
def max_capture_events=(value)
|
144
|
-
mutex.synchronize do
|
145
|
-
@max_capture_events = value
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
def capture_limit_exceeded?
|
150
|
-
mutex.synchronize do
|
151
|
-
max_capture_events > 0 && capture_events_count >= max_capture_events
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
134
|
def disable_capturing!
|
156
135
|
mutex.synchronize do
|
157
136
|
@enabled = false
|
@@ -170,7 +149,6 @@ class EnhancedErrors
|
|
170
149
|
@rspec_tracepoint = nil
|
171
150
|
@minitest_trace = nil
|
172
151
|
@exception_trace = nil
|
173
|
-
@capture_events_count = 0
|
174
152
|
@enabled = true
|
175
153
|
end
|
176
154
|
end
|
@@ -183,25 +161,22 @@ class EnhancedErrors
|
|
183
161
|
|
184
162
|
def override_rspec_message(example, binding_or_bindings)
|
185
163
|
exception_obj = example.exception
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
164
|
+
return if exception_obj.nil?
|
165
|
+
|
166
|
+
from_bindings = [binding_or_bindings].flatten.compact
|
167
|
+
case exception_obj.class.to_s
|
168
|
+
when 'RSpec::Core::MultipleExceptionError'
|
190
169
|
exception_obj.all_exceptions.each do |exception|
|
191
|
-
override_exception_message(exception,
|
170
|
+
override_exception_message(exception, from_bindings + exception.binding_infos)
|
192
171
|
end
|
193
|
-
|
172
|
+
when 'RSpec::Expectations::ExpectationNotMetError'
|
194
173
|
override_exception_message(exception_obj, binding_or_bindings)
|
174
|
+
else
|
175
|
+
override_exception_message(exception_obj, from_bindings + exception_obj.binding_infos)
|
195
176
|
end
|
196
177
|
end
|
197
178
|
|
198
179
|
def override_exception_message(exception, binding_or_bindings)
|
199
|
-
return nil unless exception && exception.respond_to?(:message)
|
200
|
-
test_binding = !(binding_or_bindings.nil? || binding_or_bindings.empty?)
|
201
|
-
exception_binding = (exception.binding_infos.length > 0)
|
202
|
-
has_message = !(exception.respond_to?(:unaltered_message))
|
203
|
-
return nil unless (test_binding || exception_binding) && has_message
|
204
|
-
|
205
180
|
variable_str = EnhancedErrors.format(binding_or_bindings)
|
206
181
|
message_str = exception.message
|
207
182
|
exception.define_singleton_method(:unaltered_message) { message_str }
|
@@ -224,14 +199,8 @@ class EnhancedErrors
|
|
224
199
|
@output_format = nil
|
225
200
|
@eligible_for_capture = nil
|
226
201
|
@original_global_variables = nil
|
227
|
-
@override_messages = override_messages
|
228
|
-
|
229
|
-
# Ensure these are not nil
|
230
|
-
if @max_capture_events.nil?
|
231
|
-
@max_capture_events = -1
|
232
|
-
end
|
233
|
-
@capture_events_count ||= 0
|
234
202
|
|
203
|
+
@override_messages = override_messages
|
235
204
|
@rspec_failure_message_loaded = true
|
236
205
|
|
237
206
|
@enabled = enabled
|
@@ -252,32 +221,12 @@ class EnhancedErrors
|
|
252
221
|
|
253
222
|
validate_and_set_capture_events(capture_events)
|
254
223
|
|
255
|
-
# If max_capture_events == 0, capturing is off from the start.
|
256
|
-
if @max_capture_events == 0
|
257
|
-
@enabled = false
|
258
|
-
return
|
259
|
-
end
|
260
|
-
|
261
224
|
events = @capture_events ? @capture_events.to_a : default_capture_events
|
262
225
|
@exception_trace = TracePoint.new(*events) do |tp|
|
263
226
|
handle_tracepoint_event(tp)
|
264
227
|
end
|
265
228
|
|
266
|
-
|
267
|
-
if @enabled && (@max_capture_events == -1 || @capture_events_count < @max_capture_events)
|
268
|
-
@exception_trace.enable
|
269
|
-
end
|
270
|
-
end
|
271
|
-
end
|
272
|
-
|
273
|
-
def safe_prepend_module(target_class, mod)
|
274
|
-
mutex.synchronize do
|
275
|
-
if defined?(target_class) && target_class.is_a?(Module)
|
276
|
-
target_class.prepend(mod)
|
277
|
-
true
|
278
|
-
else
|
279
|
-
false
|
280
|
-
end
|
229
|
+
@exception_trace.enable if @enabled
|
281
230
|
end
|
282
231
|
end
|
283
232
|
|
@@ -286,6 +235,7 @@ class EnhancedErrors
|
|
286
235
|
end
|
287
236
|
|
288
237
|
def start_minitest_binding_capture
|
238
|
+
EnhancedExceptionContext.clear_all
|
289
239
|
@enabled = true if @enabled.nil?
|
290
240
|
return unless @enabled
|
291
241
|
mutex.synchronize do
|
@@ -298,7 +248,6 @@ class EnhancedErrors
|
|
298
248
|
end
|
299
249
|
|
300
250
|
def stop_minitest_binding_capture
|
301
|
-
disable_capturing! if capture_limit_exceeded?
|
302
251
|
mutex.synchronize do
|
303
252
|
@minitest_trace&.disable
|
304
253
|
@minitest_trace = nil
|
@@ -320,6 +269,7 @@ class EnhancedErrors
|
|
320
269
|
end
|
321
270
|
|
322
271
|
def start_rspec_binding_capture
|
272
|
+
EnhancedExceptionContext.clear_all
|
323
273
|
@enabled = true if @enabled.nil?
|
324
274
|
return unless @enabled
|
325
275
|
|
@@ -328,37 +278,38 @@ class EnhancedErrors
|
|
328
278
|
@capture_next_binding = false
|
329
279
|
@rspec_tracepoint&.disable
|
330
280
|
|
331
|
-
@rspec_tracepoint = TracePoint.new(:raise
|
332
|
-
# puts "name #{tp.raised_exception.class.name rescue ''} method:#{tp.method_id} tp.binding:#{tp.binding.local_variables rescue ''}"
|
333
|
-
# puts "event: #{tp.event} defined_class#{class_to_string(tp.defined_class)} #{tp.path}:#{tp.lineno} #{tp.callee_id} "
|
334
|
-
# This trickery below is to help us identify the anonymous block return we want to grab
|
335
|
-
# Very kluge-y and edge cases have grown it, but it works
|
336
|
-
if tp.event == :b_return
|
337
|
-
if RSPEC_HANDLER_NAMES.include?(class_to_string(tp.defined_class))
|
338
|
-
@capture_next_binding = :next
|
339
|
-
next
|
340
|
-
end
|
341
|
-
next unless @capture_next_binding
|
342
|
-
if @capture_next_binding == :next || @capture_next_binding == :next_matching && is_rspec_example?(tp)
|
343
|
-
@capture_next_binding = false
|
344
|
-
@rspec_example_binding = tp.binding
|
345
|
-
end
|
346
|
-
elsif tp.event == :raise
|
281
|
+
@rspec_tracepoint = TracePoint.new(:raise) do |tp|
|
347
282
|
class_name = tp.raised_exception.class.name
|
348
283
|
case class_name
|
349
284
|
when 'RSpec::Expectations::ExpectationNotMetError'
|
350
|
-
|
285
|
+
start_rspec_binding_trap
|
351
286
|
else
|
352
287
|
handle_tracepoint_event(tp)
|
353
288
|
end
|
354
289
|
end
|
355
290
|
end
|
356
291
|
@rspec_tracepoint.enable
|
292
|
+
end
|
293
|
+
|
294
|
+
# grab the next rspec binding that goes by, and then stop the expensive listening trace
|
295
|
+
def start_rspec_binding_trap
|
296
|
+
@rspec_binding_trap = TracePoint.new(:b_return) do |tp|
|
297
|
+
# kluge-y hack and will be a pain to maintain
|
298
|
+
if tp.callee_id == :handle_matcher
|
299
|
+
@capture_next_binding = :next
|
300
|
+
next
|
301
|
+
end
|
302
|
+
next unless @capture_next_binding
|
303
|
+
@capture_next_binding = false
|
304
|
+
@rspec_example_binding = tp.binding
|
305
|
+
@rspec_binding_trap.disable
|
306
|
+
@rspec_binding_trap = nil
|
357
307
|
end
|
308
|
+
@rspec_binding_trap.enable
|
358
309
|
end
|
359
310
|
|
311
|
+
|
360
312
|
def stop_rspec_binding_capture
|
361
|
-
disable_capturing! if capture_limit_exceeded?
|
362
313
|
mutex.synchronize do
|
363
314
|
@rspec_tracepoint&.disable
|
364
315
|
@rspec_tracepoint = nil
|
@@ -502,16 +453,8 @@ class EnhancedErrors
|
|
502
453
|
def running_in_ci?
|
503
454
|
mutex.synchronize do
|
504
455
|
return @running_in_ci if defined?(@running_in_ci)
|
505
|
-
|
506
|
-
|
507
|
-
'JENKINS' => ENV['JENKINS'],
|
508
|
-
'GITHUB_ACTIONS' => ENV['GITHUB_ACTIONS'],
|
509
|
-
'CIRCLECI' => ENV['CIRCLECI'],
|
510
|
-
'TRAVIS' => ENV['TRAVIS'],
|
511
|
-
'APPVEYOR' => ENV['APPVEYOR'],
|
512
|
-
'GITLAB_CI' => ENV['GITLAB_CI']
|
513
|
-
}
|
514
|
-
@running_in_ci = ci_env_vars.any? { |_, value| value.to_s.downcase == 'true' }
|
456
|
+
|
457
|
+
@running_in_ci = CI_ENV_VARS.any? { |_, value| value.to_s.downcase == 'true' }
|
515
458
|
end
|
516
459
|
end
|
517
460
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: enhanced_errors
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.
|
4
|
+
version: 3.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eric Beland
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-12-
|
11
|
+
date: 2024-12-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: awesome_print
|
@@ -141,7 +141,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
141
141
|
- !ruby/object:Gem::Version
|
142
142
|
version: '0'
|
143
143
|
requirements: []
|
144
|
-
rubygems_version: 3.
|
144
|
+
rubygems_version: 3.5.22
|
145
145
|
signing_key:
|
146
146
|
specification_version: 4
|
147
147
|
summary: Automatically enhance your errors with messages containing variable values
|