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.
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'>&#39;</span><span class='tstring_content'>enhanced_errors</span><span class='tstring_end'>&#39;</span></span>
103
+ <span class='id identifier rubyid_require'>require</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>awesome_print</span><span class='tstring_end'>&#39;</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
- <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>
103
- <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>
104
- <span class='kw'>end</span>
105
-
106
- <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>
107
- <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>
108
- <span class='kw'>end</span>
109
-
110
- <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>
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_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>
112
- <span class='kw'>end</span>
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[&#39;enhanced_errors&#39;] == &#39;true&#39;
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'>&#39;</span><span class='tstring_content'>enhanced_errors</span><span class='tstring_end'>&#39;</span></span>
121
- <span class='id identifier rubyid_require'>require</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>enhanced/minitest_patch</span><span class='tstring_end'>&#39;</span></span>
122
-
133
+ <span class='id identifier rubyid_require'>require</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>awesome_print</span><span class='tstring_end'>&#39;</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'>&#39;</span><span class='tstring_content'>enhanced/minitest_patch</span><span class='tstring_end'>&#39;</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>&lt;img src=“./doc/images/enhanced-error.png” style=“height: 215px; width: 429px;”&gt;&lt;/img&gt; <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, also be fine in production (if data security, redaction, PII, access, and encryption concerns were all addressed. Big list, but another option is to selectively enable targeted capture.</p>
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 <strong>NoMemoryError</strong>.</p>
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 made safe for production use, giving you valuable insights without compromising performance. I would not enable it in production <em>yet</em>.</p>
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 at <a href="https://github.com/your_username/enhanced_errors">github.com/your_username/enhanced_errors</a>.</p>
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 Tue Dec 17 21:43:58 2024 by
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.3.6).
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="EnhancedExceptionContext.html#clear_all-instance_method" title="EnhancedExceptionContext#clear_all (method)">#clear_all</a></span>
133
- <small>EnhancedExceptionContext</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="EnhancedExceptionContext.html#clear_context-instance_method" title="EnhancedExceptionContext#clear_context (method)">#clear_context</a></span>
141
- <small>EnhancedExceptionContext</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="EnhancedExceptionContext.html#context_for-instance_method" title="EnhancedExceptionContext#context_for (method)">#context_for</a></span>
173
- <small>EnhancedExceptionContext</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#skip_list-class_method" title="EnhancedErrors.skip_list (method)">skip_list</a></span>
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#start_minitest_binding_capture-class_method" title="EnhancedErrors.start_minitest_binding_capture (method)">start_minitest_binding_capture</a></span>
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="EnhancedExceptionContext.html#store_context-instance_method" title="EnhancedExceptionContext#store_context (method)">#store_context</a></span>
445
- <small>EnhancedExceptionContext</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="EnhancedExceptionContext.html" title="EnhancedExceptionContext (module)">EnhancedExceptionContext</a></span>, <span class='object_link'><a href="ExceptionBindingInfos.html" title="ExceptionBindingInfos (module)">ExceptionBindingInfos</a></span>, <span class='object_link'><a href="Minitest.html" title="Minitest (module)">Minitest</a></span>
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="Context.html" title="Context (class)">Context</a></span>, <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>
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'>SystemExit</span><span class='words_sep'> </span><span class='tstring_content'>NoMemoryError</span><span class='words_sep'> </span><span class='tstring_content'>SignalException</span><span class='words_sep'> </span><span class='tstring_content'>Interrupt</span><span class='words_sep'> </span><span class='tstring_content'>ScriptError</span><span class='words_sep'> </span><span class='tstring_content'>LoadError</span><span class='words_sep'>
106
- </span><span class='tstring_content'>NotImplementedError</span><span class='words_sep'> </span><span class='tstring_content'>SyntaxError</span><span class='words_sep'> </span><span class='tstring_content'>RSpec::Expectations::ExpectationNotMetError</span><span class='words_sep'>
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 Tue Dec 17 21:43:58 2024 by
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.3.6).
135
+ 0.9.37 (ruby-3.4.1).
126
136
  </div>
127
137
 
128
138
  </div>
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "enhanced_errors"
3
- spec.version = "3.0.3"
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."
@@ -1,7 +1,9 @@
1
- class Context
2
- attr_accessor :binding_infos
1
+ module Enhanced
2
+ class Context
3
+ attr_accessor :binding_infos
3
4
 
4
- def initialize
5
- @binding_infos = []
5
+ def initialize
6
+ @binding_infos = []
7
+ end
6
8
  end
7
- end
9
+ end
@@ -1,55 +1,54 @@
1
1
  # exception.rb
2
- require_relative 'enhanced_exception_context'
3
-
4
- module ExceptionBindingInfos
5
- def binding_infos
6
- ctx = EnhancedExceptionContext.context_for(self)
7
- unless ctx
8
- ctx = Context.new
9
- EnhancedExceptionContext.store_context(self, ctx)
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
- def captured_variables
15
- if binding_infos.any?
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
- else
19
+ rescue
19
20
  ''
20
21
  end
21
- rescue
22
- ''
23
- end
24
22
 
25
- private
23
+ private
26
24
 
27
- def select_binding_infos
28
- # Preference:
29
- # 1. First 'raise' binding that isn't from a library (gem).
30
- # 2. If none, the first binding.
31
- # 3. The last 'rescue' binding if available.
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
- bindings_of_interest = []
31
+ bindings_of_interest = []
34
32
 
35
- first_app_raise = binding_infos.find do |info|
36
- info[:capture_event] == 'raise' && !info[:library]
37
- end
38
- bindings_of_interest << first_app_raise if first_app_raise
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
- if bindings_of_interest.empty? && binding_infos.first
41
- bindings_of_interest << binding_infos.first
42
- end
38
+ if bindings_of_interest.empty? && binding_infos.first
39
+ bindings_of_interest << binding_infos.first
40
+ end
43
41
 
44
- last_rescue = binding_infos.reverse.find do |info|
45
- info[:capture_event] == 'rescue'
46
- end
47
- bindings_of_interest << last_rescue if last_rescue
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
- bindings_of_interest.compact
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
- EnhancedExceptionContext.clear_all
12
+ Enhanced::ExceptionContext.clear_all
13
13
  rescue => e
14
14
  puts "Ignored error during error enhancement: #{e}"
15
15
  end