enhanced_errors 3.0.3 → 3.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +43 -35
- data/benchmark/benchmark.rb +31 -29
- data/benchmark/memory_bench.rb +1 -1
- data/benchmark/result.txt +11 -0
- data/doc/Enhanced/Colors.html +2 -2
- data/doc/Enhanced/Context.html +283 -0
- data/doc/Enhanced/ExceptionBindingInfos.html +249 -0
- data/doc/Enhanced/ExceptionContext.html +397 -0
- data/doc/Enhanced.html +8 -4
- data/doc/EnhancedErrors.html +395 -275
- data/doc/EnhancedExceptionContext.html +15 -15
- data/doc/Exception.html +5 -5
- data/doc/ExceptionBindingInfos.html +2 -2
- data/doc/Minitest.html +3 -3
- data/doc/_index.html +12 -6
- data/doc/class_list.html +1 -1
- data/doc/file.README.html +39 -44
- data/doc/index.html +39 -44
- data/doc/method_list.html +34 -18
- data/doc/top-level-namespace.html +18 -8
- data/enhanced_errors.gemspec +1 -1
- data/lib/enhanced/context.rb +7 -5
- data/lib/enhanced/exception.rb +35 -36
- data/lib/enhanced/exception_context.rb +49 -0
- data/lib/enhanced/minitest_patch.rb +1 -1
- data/lib/enhanced_errors.rb +147 -98
- metadata +8 -13
- data/.yardoc/checksums +0 -6
- data/.yardoc/complete +0 -0
- data/.yardoc/object_types +0 -0
- data/.yardoc/objects/root.dat +0 -0
- data/.yardoc/proxy_types +0 -0
- data/lib/enhanced/enhanced_exception_context.rb +0 -47
data/doc/index.html
CHANGED
@@ -97,29 +97,41 @@
|
|
97
97
|
|
98
98
|
<p>Use EnhancedErrors with RSpec for test-specific exception capturing, ideal for CI and local testing without impacting production.</p>
|
99
99
|
|
100
|
-
<pre class="code ruby"><code class="ruby"
|
100
|
+
<pre class="code ruby"><code class="ruby"><span class='comment'># usually in spec_helper.rb or rails_helper.rb
|
101
|
+
</span>
|
102
|
+
<span class='id identifier rubyid_require'>require</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>enhanced_errors</span><span class='tstring_end'>'</span></span>
|
103
|
+
<span class='id identifier rubyid_require'>require</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>awesome_print</span><span class='tstring_end'>'</span></span> <span class='comment'># Optional, for better output
|
104
|
+
</span>
|
101
105
|
<span class='const'>RSpec</span><span class='period'>.</span><span class='id identifier rubyid_configure'>configure</span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_config'>config</span><span class='op'>|</span>
|
102
|
-
|
103
|
-
|
104
|
-
<span class='
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
106
|
+
|
107
|
+
<span class='comment'># Along with the requires, add this to your RSpec config to enhance your RSpec output
|
108
|
+
</span> <span class='comment'># Consider driving the config with an environment variable like this to make it configurable per-user or run
|
109
|
+
</span> <span class='comment'># if ENV['enhanced_errors'] == 'true'
|
110
|
+
</span> <span class='id identifier rubyid_config'>config</span><span class='period'>.</span><span class='id identifier rubyid_before'>before</span><span class='lparen'>(</span><span class='symbol'>:example</span><span class='rparen'>)</span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid__example'>_example</span><span class='op'>|</span>
|
111
|
+
<span class='const'><span class='object_link'><a href="EnhancedErrors.html" title="EnhancedErrors (class)">EnhancedErrors</a></span></span><span class='period'>.</span><span class='id identifier rubyid_start_rspec_binding_capture'><span class='object_link'><a href="EnhancedErrors.html#start_rspec_binding_capture-class_method" title="EnhancedErrors.start_rspec_binding_capture (method)">start_rspec_binding_capture</a></span></span>
|
112
|
+
<span class='kw'>end</span>
|
113
|
+
|
114
|
+
<span class='id identifier rubyid_config'>config</span><span class='period'>.</span><span class='id identifier rubyid_before'>before</span><span class='lparen'>(</span><span class='symbol'>:example</span><span class='rparen'>)</span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid__example'>_example</span><span class='op'>|</span>
|
115
|
+
<span class='const'><span class='object_link'><a href="EnhancedErrors.html" title="EnhancedErrors (class)">EnhancedErrors</a></span></span><span class='period'>.</span><span class='id identifier rubyid_start_rspec_binding_capture'><span class='object_link'><a href="EnhancedErrors.html#start_rspec_binding_capture-class_method" title="EnhancedErrors.start_rspec_binding_capture (method)">start_rspec_binding_capture</a></span></span>
|
116
|
+
<span class='kw'>end</span>
|
117
|
+
|
118
|
+
<span class='id identifier rubyid_config'>config</span><span class='period'>.</span><span class='id identifier rubyid_after'>after</span><span class='lparen'>(</span><span class='symbol'>:example</span><span class='rparen'>)</span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_example'>example</span><span class='op'>|</span>
|
119
|
+
<span class='const'><span class='object_link'><a href="EnhancedErrors.html" title="EnhancedErrors (class)">EnhancedErrors</a></span></span><span class='period'>.</span><span class='id identifier rubyid_override_rspec_message'><span class='object_link'><a href="EnhancedErrors.html#override_rspec_message-class_method" title="EnhancedErrors.override_rspec_message (method)">override_rspec_message</a></span></span><span class='lparen'>(</span><span class='id identifier rubyid_example'>example</span><span class='comma'>,</span> <span class='const'><span class='object_link'><a href="EnhancedErrors.html" title="EnhancedErrors (class)">EnhancedErrors</a></span></span><span class='period'>.</span><span class='id identifier rubyid_stop_rspec_binding_capture'><span class='object_link'><a href="EnhancedErrors.html#stop_rspec_binding_capture-class_method" title="EnhancedErrors.stop_rspec_binding_capture (method)">stop_rspec_binding_capture</a></span></span><span class='rparen'>)</span>
|
120
|
+
<span class='kw'>end</span>
|
121
|
+
<span class='comment'># end
|
122
|
+
</span>
|
113
123
|
<span class='kw'>end</span>
|
114
124
|
</code></pre>
|
115
125
|
|
116
126
|
<p><br></p>
|
117
127
|
|
128
|
+
<p>”””</p>
|
129
|
+
|
118
130
|
<h2 id="label-MiniTest+Setup">MiniTest Setup</h2>
|
119
131
|
|
120
132
|
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_require'>require</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>enhanced_errors</span><span class='tstring_end'>'</span></span>
|
121
|
-
<span class='id identifier rubyid_require'>require</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>
|
122
|
-
|
133
|
+
<span class='id identifier rubyid_require'>require</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>awesome_print</span><span class='tstring_end'>'</span></span> <span class='comment'># Optional, for better output
|
134
|
+
</span><span class='id identifier rubyid_require'>require</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>enhanced/minitest_patch</span><span class='tstring_end'>'</span></span>
|
123
135
|
<span class='comment'># Once the patch is loaded, it should just work!
|
124
136
|
</span></code></pre>
|
125
137
|
|
@@ -169,10 +181,14 @@
|
|
169
181
|
|
170
182
|
<p><img src=“./doc/images/enhanced-error.png” style=“height: 215px; width: 429px;”></img> <br></p>
|
171
183
|
|
184
|
+
<p>EnhancedErrors use-cases: * Handle test and CI failures faster by skipping that pesky “reproduction” step. * LLM-candy - Feed debug output with variable values into your LLM, making state examine-able * Debug deep-stack errors and reduce mean time to resolution (MTTR). * Address elusive “Heisenbugs” by capturing full error context preemptively. * Debug cron jobs and daemons with rich, failure-specific logs. * Catch data-driven bugs in long jobs without re-runs or extensive logging.</p>
|
185
|
+
|
172
186
|
<h2 id="label-Features">Features</h2>
|
173
187
|
<ul><li>
|
174
188
|
<p><strong>Pure Ruby</strong>: No external dependencies, C extensions, or C API calls.</p>
|
175
189
|
</li><li>
|
190
|
+
<p>**Improved RSpec and Minitest errors for straight-to-fix–look-ma-no-debugging, look-ma-no-reproducing</p>
|
191
|
+
</li><li>
|
176
192
|
<p><strong>Customizable Output</strong>: Supports multiple output formats (<code>:json</code>, <code>:plaintext</code>, <code>:terminal</code>).</p>
|
177
193
|
</li><li>
|
178
194
|
<p><strong>Flexible Hooks</strong>: Redact or modifying captured data via the <code>on_capture</code> hook. Update the final string with on_format.</p>
|
@@ -190,19 +206,6 @@
|
|
190
206
|
<p><strong>Lightweight</strong>: Minimal performance impact, as tracing is only active during exception raising.</p>
|
191
207
|
</li></ul>
|
192
208
|
|
193
|
-
<p>EnhancedErrors use-cases:</p>
|
194
|
-
<ul><li>
|
195
|
-
<p>Catch data-driven bugs without needing re-runs or extensive logging.</p>
|
196
|
-
</li><li>
|
197
|
-
<p>Debug deep-stack errors and reduce mean time to resolution (MTTR).</p>
|
198
|
-
</li><li>
|
199
|
-
<p>Handle CI failures faster by skipping reproduction steps.</p>
|
200
|
-
</li><li>
|
201
|
-
<p>Address elusive “Heisenbugs” by capturing error context preemptively.</p>
|
202
|
-
</li><li>
|
203
|
-
<p>Debug cron jobs and daemons with rich, failure-specific logs.</p>
|
204
|
-
</li></ul>
|
205
|
-
|
206
209
|
<h2 id="label-Installation">Installation</h2>
|
207
210
|
|
208
211
|
<p>Add this line to your <code>Gemfile</code>:</p>
|
@@ -267,13 +270,6 @@
|
|
267
270
|
<p>Terminal Color output: Enabled</p>
|
268
271
|
</li></ul>
|
269
272
|
</li><li>
|
270
|
-
<p><strong>Production</strong>:</p>
|
271
|
-
<ul><li>
|
272
|
-
<p>Output format: <code>:json</code></p>
|
273
|
-
</li><li>
|
274
|
-
<p>Terminal Color output: Disabled</p>
|
275
|
-
</li></ul>
|
276
|
-
</li><li>
|
277
273
|
<p><strong>CI Environment</strong>:</p>
|
278
274
|
<ul><li>
|
279
275
|
<p>Output format: <code>:plaintext</code></p>
|
@@ -368,10 +364,6 @@
|
|
368
364
|
<p>These exceptions are always ignored:</p>
|
369
365
|
|
370
366
|
<pre class="code ruby"><code class="ruby"><span class='const'>SystemExit</span> <span class='const'>NoMemoryError</span> <span class='const'>SignalException</span> <span class='const'>Interrupt</span>
|
371
|
-
<span class='const'>ScriptError</span> <span class='const'>LoadError</span> <span class='const'>NotImplementedError</span> <span class='const'>SyntaxError</span>
|
372
|
-
<span class='const'>RSpec</span><span class='op'>::</span><span class='const'>Expectations</span><span class='op'>::</span><span class='const'>ExpectationNotMetError</span>
|
373
|
-
<span class='const'>RSpec</span><span class='op'>::</span><span class='const'>Matchers</span><span class='op'>::</span><span class='const'>BuiltIn</span><span class='op'>::</span><span class='const'>RaiseError</span>
|
374
|
-
<span class='const'>SystemStackError</span> <span class='const'>Psych</span><span class='op'>::</span><span class='const'>BadAlias</span>
|
375
367
|
</code></pre>
|
376
368
|
|
377
369
|
<p>While this is close to “Things that don’t descend from StandardError”, it’s not exactly that.</p>
|
@@ -458,7 +450,7 @@
|
|
458
450
|
<ul><li>
|
459
451
|
<p>EnhancedErrors won’t interrupt CI, but it lets me know what happened <em>without</em> reproduction steps</p>
|
460
452
|
</li><li>
|
461
|
-
<p>EnhancedErrors could, theoretically,
|
453
|
+
<p>EnhancedErrors could, theoretically, be fine in production (if data security, redaction, PII, access, and encryption concerns were addressed). Big list, but another option is to selectively enable targeted capture. The hooks provide a place to handle things of this sort.</p>
|
462
454
|
</li><li>
|
463
455
|
<p>Has decent performance characteristics</p>
|
464
456
|
</li><li>
|
@@ -471,14 +463,17 @@
|
|
471
463
|
<ul><li>
|
472
464
|
<p><strong>Small Overhead</strong>: Since TracePoint is only activated during exception raising and rescuing, the performance impact is negligible during normal operation. (Benchmark included)</p>
|
473
465
|
</li><li>
|
474
|
-
<p><strong>TBD</strong>: Memory considerations. This does capture data when an exception happens. EnhancedErrors hides under the bed when it sees
|
466
|
+
<p><strong>TBD</strong>: Memory considerations. This does capture data when an exception happens. EnhancedErrors hides under the bed when it sees the scariest exceptions.</p>
|
475
467
|
</li><li>
|
476
|
-
<p><strong>Goal: Production Safety</strong>: The gem is designed to, eventually, be
|
468
|
+
<p><strong>Goal: Production Safety</strong>: The gem is designed to, eventually, be suitable for production use. I might not enable it in production <em>yet</em> as it is pretty new. It would require a thoughtful approach (perhaps behind a feature flag, or only capturing targeted exceptions via the eligible for capture feature).</p>
|
477
469
|
</li></ul>
|
478
470
|
|
479
471
|
<h2 id="label-Contributing">Contributing</h2>
|
480
472
|
|
481
|
-
<p>Bug reports and pull requests are welcome on GitHub
|
473
|
+
<p>Bug reports and pull requests are welcome on GitHub.</p>
|
474
|
+
<ul><li>
|
475
|
+
<p>Please include tests to demonstrate your contribution working.</p>
|
476
|
+
</li></ul>
|
482
477
|
|
483
478
|
<h2 id="label-License">License</h2>
|
484
479
|
|
@@ -486,9 +481,9 @@
|
|
486
481
|
</div></div>
|
487
482
|
|
488
483
|
<div id="footer">
|
489
|
-
Generated on
|
484
|
+
Generated on Wed Dec 25 13:01:48 2024 by
|
490
485
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
491
|
-
0.9.37 (ruby-3.
|
486
|
+
0.9.37 (ruby-3.4.1).
|
492
487
|
</div>
|
493
488
|
|
494
489
|
</div>
|
data/doc/method_list.html
CHANGED
@@ -73,16 +73,16 @@
|
|
73
73
|
|
74
74
|
<li class="even ">
|
75
75
|
<div class="item">
|
76
|
-
<span class='object_link'><a href="Context.html#binding_infos-instance_method" title="Context#binding_infos (method)">#binding_infos</a></span>
|
77
|
-
<small>Context</small>
|
76
|
+
<span class='object_link'><a href="Enhanced/Context.html#binding_infos-instance_method" title="Enhanced::Context#binding_infos (method)">#binding_infos</a></span>
|
77
|
+
<small>Enhanced::Context</small>
|
78
78
|
</div>
|
79
79
|
</li>
|
80
80
|
|
81
81
|
|
82
82
|
<li class="odd ">
|
83
83
|
<div class="item">
|
84
|
-
<span class='object_link'><a href="ExceptionBindingInfos.html#binding_infos-instance_method" title="ExceptionBindingInfos#binding_infos (method)">#binding_infos</a></span>
|
85
|
-
<small>ExceptionBindingInfos</small>
|
84
|
+
<span class='object_link'><a href="Enhanced/ExceptionBindingInfos.html#binding_infos-instance_method" title="Enhanced::ExceptionBindingInfos#binding_infos (method)">#binding_infos</a></span>
|
85
|
+
<small>Enhanced::ExceptionBindingInfos</small>
|
86
86
|
</div>
|
87
87
|
</li>
|
88
88
|
|
@@ -113,8 +113,8 @@
|
|
113
113
|
|
114
114
|
<li class="odd ">
|
115
115
|
<div class="item">
|
116
|
-
<span class='object_link'><a href="ExceptionBindingInfos.html#captured_variables-instance_method" title="ExceptionBindingInfos#captured_variables (method)">#captured_variables</a></span>
|
117
|
-
<small>ExceptionBindingInfos</small>
|
116
|
+
<span class='object_link'><a href="Enhanced/ExceptionBindingInfos.html#captured_variables-instance_method" title="Enhanced::ExceptionBindingInfos#captured_variables (method)">#captured_variables</a></span>
|
117
|
+
<small>Enhanced::ExceptionBindingInfos</small>
|
118
118
|
</div>
|
119
119
|
</li>
|
120
120
|
|
@@ -129,16 +129,16 @@
|
|
129
129
|
|
130
130
|
<li class="odd ">
|
131
131
|
<div class="item">
|
132
|
-
<span class='object_link'><a href="
|
133
|
-
<small>
|
132
|
+
<span class='object_link'><a href="Enhanced/ExceptionContext.html#clear_all-instance_method" title="Enhanced::ExceptionContext#clear_all (method)">#clear_all</a></span>
|
133
|
+
<small>Enhanced::ExceptionContext</small>
|
134
134
|
</div>
|
135
135
|
</li>
|
136
136
|
|
137
137
|
|
138
138
|
<li class="even ">
|
139
139
|
<div class="item">
|
140
|
-
<span class='object_link'><a href="
|
141
|
-
<small>
|
140
|
+
<span class='object_link'><a href="Enhanced/ExceptionContext.html#clear_context-instance_method" title="Enhanced::ExceptionContext#clear_context (method)">#clear_context</a></span>
|
141
|
+
<small>Enhanced::ExceptionContext</small>
|
142
142
|
</div>
|
143
143
|
</li>
|
144
144
|
|
@@ -169,8 +169,8 @@
|
|
169
169
|
|
170
170
|
<li class="even ">
|
171
171
|
<div class="item">
|
172
|
-
<span class='object_link'><a href="
|
173
|
-
<small>
|
172
|
+
<span class='object_link'><a href="Enhanced/ExceptionContext.html#context_for-instance_method" title="Enhanced::ExceptionContext#context_for (method)">#context_for</a></span>
|
173
|
+
<small>Enhanced::ExceptionContext</small>
|
174
174
|
</div>
|
175
175
|
</li>
|
176
176
|
|
@@ -257,8 +257,8 @@
|
|
257
257
|
|
258
258
|
<li class="odd ">
|
259
259
|
<div class="item">
|
260
|
-
<span class='object_link'><a href="Context.html#initialize-instance_method" title="Context#initialize (method)">#initialize</a></span>
|
261
|
-
<small>Context</small>
|
260
|
+
<span class='object_link'><a href="Enhanced/Context.html#initialize-instance_method" title="Enhanced::Context#initialize (method)">#initialize</a></span>
|
261
|
+
<small>Enhanced::Context</small>
|
262
262
|
</div>
|
263
263
|
</li>
|
264
264
|
|
@@ -401,7 +401,7 @@
|
|
401
401
|
|
402
402
|
<li class="odd ">
|
403
403
|
<div class="item">
|
404
|
-
<span class='object_link'><a href="EnhancedErrors.html#
|
404
|
+
<span class='object_link'><a href="EnhancedErrors.html#safe_to_inspect%3F-class_method" title="EnhancedErrors.safe_to_inspect? (method)">safe_to_inspect?</a></span>
|
405
405
|
<small>EnhancedErrors</small>
|
406
406
|
</div>
|
407
407
|
</li>
|
@@ -409,13 +409,21 @@
|
|
409
409
|
|
410
410
|
<li class="even ">
|
411
411
|
<div class="item">
|
412
|
-
<span class='object_link'><a href="EnhancedErrors.html#
|
412
|
+
<span class='object_link'><a href="EnhancedErrors.html#skip_list-class_method" title="EnhancedErrors.skip_list (method)">skip_list</a></span>
|
413
413
|
<small>EnhancedErrors</small>
|
414
414
|
</div>
|
415
415
|
</li>
|
416
416
|
|
417
417
|
|
418
418
|
<li class="odd ">
|
419
|
+
<div class="item">
|
420
|
+
<span class='object_link'><a href="EnhancedErrors.html#start_minitest_binding_capture-class_method" title="EnhancedErrors.start_minitest_binding_capture (method)">start_minitest_binding_capture</a></span>
|
421
|
+
<small>EnhancedErrors</small>
|
422
|
+
</div>
|
423
|
+
</li>
|
424
|
+
|
425
|
+
|
426
|
+
<li class="even ">
|
419
427
|
<div class="item">
|
420
428
|
<span class='object_link'><a href="EnhancedErrors.html#start_rspec_binding_capture-class_method" title="EnhancedErrors.start_rspec_binding_capture (method)">start_rspec_binding_capture</a></span>
|
421
429
|
<small>EnhancedErrors</small>
|
@@ -423,6 +431,14 @@
|
|
423
431
|
</li>
|
424
432
|
|
425
433
|
|
434
|
+
<li class="odd ">
|
435
|
+
<div class="item">
|
436
|
+
<span class='object_link'><a href="EnhancedErrors.html#start_rspec_binding_trap-class_method" title="EnhancedErrors.start_rspec_binding_trap (method)">start_rspec_binding_trap</a></span>
|
437
|
+
<small>EnhancedErrors</small>
|
438
|
+
</div>
|
439
|
+
</li>
|
440
|
+
|
441
|
+
|
426
442
|
<li class="even ">
|
427
443
|
<div class="item">
|
428
444
|
<span class='object_link'><a href="EnhancedErrors.html#stop_minitest_binding_capture-class_method" title="EnhancedErrors.stop_minitest_binding_capture (method)">stop_minitest_binding_capture</a></span>
|
@@ -441,8 +457,8 @@
|
|
441
457
|
|
442
458
|
<li class="even ">
|
443
459
|
<div class="item">
|
444
|
-
<span class='object_link'><a href="
|
445
|
-
<small>
|
460
|
+
<span class='object_link'><a href="Enhanced/ExceptionContext.html#store_context-instance_method" title="Enhanced::ExceptionContext#store_context (method)">#store_context</a></span>
|
461
|
+
<small>Enhanced::ExceptionContext</small>
|
446
462
|
</div>
|
447
463
|
</li>
|
448
464
|
|
@@ -82,11 +82,11 @@
|
|
82
82
|
<p class="children">
|
83
83
|
|
84
84
|
|
85
|
-
<strong class="modules">Modules:</strong> <span class='object_link'><a href="Enhanced.html" title="Enhanced (module)">Enhanced</a></span>, <span class='object_link'><a href="
|
85
|
+
<strong class="modules">Modules:</strong> <span class='object_link'><a href="Enhanced.html" title="Enhanced (module)">Enhanced</a></span>, <span class='object_link'><a href="Minitest.html" title="Minitest (module)">Minitest</a></span>
|
86
86
|
|
87
87
|
|
88
88
|
|
89
|
-
<strong class="classes">Classes:</strong> <span class='object_link'><a href="
|
89
|
+
<strong class="classes">Classes:</strong> <span class='object_link'><a href="EnhancedErrors.html" title="EnhancedErrors (class)">EnhancedErrors</a></span>, <span class='object_link'><a href="Exception.html" title="Exception (class)">Exception</a></span>
|
90
90
|
|
91
91
|
|
92
92
|
</p>
|
@@ -100,11 +100,21 @@
|
|
100
100
|
<dl class="constants">
|
101
101
|
|
102
102
|
<dt id="IGNORED_EXCEPTIONS-constant" class="">IGNORED_EXCEPTIONS =
|
103
|
-
|
103
|
+
<div class="docstring">
|
104
|
+
<div class="discussion">
|
105
|
+
|
106
|
+
<p>Exceptions we could handle but overlook for other reasons. These class constants are not always loaded and generally are only be available when ‘required`, so we detect them by strings.</p>
|
107
|
+
|
108
|
+
|
109
|
+
</div>
|
110
|
+
</div>
|
111
|
+
<div class="tags">
|
112
|
+
|
113
|
+
|
114
|
+
</div>
|
104
115
|
</dt>
|
105
|
-
<dd><pre class="code"><span class='qwords_beg'>%w[</span><span class='tstring_content'>
|
106
|
-
</span><span class='tstring_content'>
|
107
|
-
</span><span class='tstring_content'>RSpec::Matchers::BuiltIn::RaiseError</span><span class='words_sep'> </span><span class='tstring_content'>SystemStackError</span><span class='words_sep'> </span><span class='tstring_content'>Psych::BadAlias</span><span class='tstring_end'>]</span></span></pre></dd>
|
116
|
+
<dd><pre class="code"><span class='qwords_beg'>%w[</span><span class='tstring_content'>RSpec::Expectations::ExpectationNotMetError</span><span class='words_sep'> </span><span class='tstring_content'>RSpec::Matchers::BuiltIn::RaiseError</span><span class='words_sep'>
|
117
|
+
</span><span class='tstring_content'>JSON::ParserError</span><span class='words_sep'> </span><span class='tstring_content'>Zlib::Error</span><span class='words_sep'> </span><span class='tstring_content'>OpenSSL::SSL::SSLError</span><span class='words_sep'> </span><span class='tstring_content'>Psych::Exception</span><span class='tstring_end'>]</span></span></pre></dd>
|
108
118
|
|
109
119
|
</dl>
|
110
120
|
|
@@ -120,9 +130,9 @@
|
|
120
130
|
</div>
|
121
131
|
|
122
132
|
<div id="footer">
|
123
|
-
Generated on
|
133
|
+
Generated on Wed Dec 25 13:01:48 2024 by
|
124
134
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
125
|
-
0.9.37 (ruby-3.
|
135
|
+
0.9.37 (ruby-3.4.1).
|
126
136
|
</div>
|
127
137
|
|
128
138
|
</div>
|
data/enhanced_errors.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |spec|
|
2
2
|
spec.name = "enhanced_errors"
|
3
|
-
spec.version = "3.0.
|
3
|
+
spec.version = "3.0.5"
|
4
4
|
spec.authors = ["Eric Beland"]
|
5
5
|
|
6
6
|
spec.summary = "Automatically enhance your errors with messages containing variable values from the moment they were raised."
|
data/lib/enhanced/context.rb
CHANGED
data/lib/enhanced/exception.rb
CHANGED
@@ -1,55 +1,54 @@
|
|
1
1
|
# exception.rb
|
2
|
-
require_relative '
|
3
|
-
|
4
|
-
module
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
ctx
|
9
|
-
|
2
|
+
require_relative 'exception_context'
|
3
|
+
|
4
|
+
module Enhanced
|
5
|
+
module ExceptionBindingInfos
|
6
|
+
def binding_infos
|
7
|
+
ctx = Enhanced::ExceptionContext.context_for(self)
|
8
|
+
unless ctx
|
9
|
+
ctx = Context.new
|
10
|
+
Enhanced::ExceptionContext.store_context(self, ctx)
|
11
|
+
end
|
12
|
+
ctx.binding_infos
|
10
13
|
end
|
11
|
-
ctx.binding_infos
|
12
|
-
end
|
13
14
|
|
14
|
-
|
15
|
-
|
15
|
+
def captured_variables
|
16
|
+
return '' unless binding_infos&.any?
|
16
17
|
bindings_of_interest = select_binding_infos
|
17
18
|
EnhancedErrors.format(bindings_of_interest)
|
18
|
-
|
19
|
+
rescue
|
19
20
|
''
|
20
21
|
end
|
21
|
-
rescue
|
22
|
-
''
|
23
|
-
end
|
24
22
|
|
25
|
-
|
23
|
+
private
|
26
24
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
25
|
+
def select_binding_infos
|
26
|
+
# Preference:
|
27
|
+
# 1. First 'raise' binding that isn't from a library (gem).
|
28
|
+
# 2. If none, the first binding.
|
29
|
+
# 3. The last 'rescue' binding if available.
|
32
30
|
|
33
|
-
|
31
|
+
bindings_of_interest = []
|
34
32
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
33
|
+
first_app_raise = binding_infos.find do |info|
|
34
|
+
info[:capture_event] == 'raise' && !info[:library]
|
35
|
+
end
|
36
|
+
bindings_of_interest << first_app_raise if first_app_raise
|
39
37
|
|
40
|
-
|
41
|
-
|
42
|
-
|
38
|
+
if bindings_of_interest.empty? && binding_infos.first
|
39
|
+
bindings_of_interest << binding_infos.first
|
40
|
+
end
|
43
41
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
42
|
+
last_rescue = binding_infos.reverse.find do |info|
|
43
|
+
info[:capture_event] == 'rescue'
|
44
|
+
end
|
45
|
+
bindings_of_interest << last_rescue if last_rescue
|
48
46
|
|
49
|
-
|
47
|
+
bindings_of_interest.compact
|
48
|
+
end
|
50
49
|
end
|
51
50
|
end
|
52
51
|
|
53
52
|
class Exception
|
54
|
-
prepend ExceptionBindingInfos
|
53
|
+
prepend Enhanced::ExceptionBindingInfos
|
55
54
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'weakref'
|
2
|
+
|
3
|
+
require_relative 'context'
|
4
|
+
|
5
|
+
require 'weakref'
|
6
|
+
require 'monitor'
|
7
|
+
|
8
|
+
module Enhanced
|
9
|
+
module ExceptionContext
|
10
|
+
extend self
|
11
|
+
|
12
|
+
REGISTRY = {}
|
13
|
+
MUTEX = Monitor.new
|
14
|
+
|
15
|
+
def store_context(exception, context)
|
16
|
+
MUTEX.synchronize do
|
17
|
+
REGISTRY[exception.object_id] = { weak_exc: WeakRef.new(exception), context: context }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def context_for(exception)
|
22
|
+
MUTEX.synchronize do
|
23
|
+
entry = REGISTRY[exception.object_id]
|
24
|
+
return nil unless entry
|
25
|
+
|
26
|
+
begin
|
27
|
+
_ = entry[:weak_exc].__getobj__ # ensure exception is still alive
|
28
|
+
entry[:context]
|
29
|
+
rescue RefError
|
30
|
+
# Exception no longer alive, clean up
|
31
|
+
REGISTRY.delete(exception.object_id)
|
32
|
+
nil
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def clear_context(exception)
|
38
|
+
MUTEX.synchronize do
|
39
|
+
REGISTRY.delete(exception.object_id)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def clear_all
|
44
|
+
MUTEX.synchronize do
|
45
|
+
REGISTRY.clear
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -9,7 +9,7 @@ module Minitest
|
|
9
9
|
begin
|
10
10
|
binding_infos = EnhancedErrors.stop_minitest_binding_capture
|
11
11
|
EnhancedErrors.override_exception_message(result.failures.last, binding_infos) if result.failures.any?
|
12
|
-
|
12
|
+
Enhanced::ExceptionContext.clear_all
|
13
13
|
rescue => e
|
14
14
|
puts "Ignored error during error enhancement: #{e}"
|
15
15
|
end
|