enhanced_errors 3.0.4 → 3.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +41 -34
- data/benchmark/result.txt +5 -7
- data/doc/Enhanced/Colors.html +2 -2
- data/doc/Enhanced/Context.html +2 -2
- data/doc/Enhanced/ExceptionBindingInfos.html +6 -12
- data/doc/Enhanced/ExceptionContext.html +2 -2
- data/doc/Enhanced.html +2 -2
- data/doc/EnhancedErrors.html +105 -101
- data/doc/Exception.html +2 -2
- data/doc/Minitest.html +2 -2
- data/doc/_index.html +2 -2
- data/doc/file.README.html +36 -46
- data/doc/index.html +36 -46
- data/doc/top-level-namespace.html +2 -2
- data/enhanced_errors.gemspec +1 -1
- data/lib/enhanced_errors.rb +14 -5
- metadata +3 -7
data/doc/Exception.html
CHANGED
@@ -111,9 +111,9 @@
|
|
111
111
|
</div>
|
112
112
|
|
113
113
|
<div id="footer">
|
114
|
-
Generated on
|
114
|
+
Generated on Wed Dec 25 13:01:48 2024 by
|
115
115
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
116
|
-
0.9.37 (ruby-3.1
|
116
|
+
0.9.37 (ruby-3.4.1).
|
117
117
|
</div>
|
118
118
|
|
119
119
|
</div>
|
data/doc/Minitest.html
CHANGED
@@ -230,9 +230,9 @@
|
|
230
230
|
</div>
|
231
231
|
|
232
232
|
<div id="footer">
|
233
|
-
Generated on
|
233
|
+
Generated on Wed Dec 25 13:01:48 2024 by
|
234
234
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
235
|
-
0.9.37 (ruby-3.1
|
235
|
+
0.9.37 (ruby-3.4.1).
|
236
236
|
</div>
|
237
237
|
|
238
238
|
</div>
|
data/doc/_index.html
CHANGED
@@ -156,9 +156,9 @@
|
|
156
156
|
</div>
|
157
157
|
|
158
158
|
<div id="footer">
|
159
|
-
Generated on
|
159
|
+
Generated on Wed Dec 25 13:01:48 2024 by
|
160
160
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
161
|
-
0.9.37 (ruby-3.1
|
161
|
+
0.9.37 (ruby-3.4.1).
|
162
162
|
</div>
|
163
163
|
|
164
164
|
</div>
|
data/doc/file.README.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,21 +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><li>
|
205
|
-
<p>LLM-food - Feed debug info with variables into an LLM, making state examine-able for it</p>
|
206
|
-
</li></ul>
|
207
|
-
|
208
209
|
<h2 id="label-Installation">Installation</h2>
|
209
210
|
|
210
211
|
<p>Add this line to your <code>Gemfile</code>:</p>
|
@@ -269,13 +270,6 @@
|
|
269
270
|
<p>Terminal Color output: Enabled</p>
|
270
271
|
</li></ul>
|
271
272
|
</li><li>
|
272
|
-
<p><strong>Production</strong>:</p>
|
273
|
-
<ul><li>
|
274
|
-
<p>Output format: <code>:json</code></p>
|
275
|
-
</li><li>
|
276
|
-
<p>Terminal Color output: Disabled</p>
|
277
|
-
</li></ul>
|
278
|
-
</li><li>
|
279
273
|
<p><strong>CI Environment</strong>:</p>
|
280
274
|
<ul><li>
|
281
275
|
<p>Output format: <code>:plaintext</code></p>
|
@@ -370,10 +364,6 @@
|
|
370
364
|
<p>These exceptions are always ignored:</p>
|
371
365
|
|
372
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>
|
373
|
-
<span class='const'>ScriptError</span> <span class='const'>LoadError</span> <span class='const'>NotImplementedError</span> <span class='const'>SyntaxError</span>
|
374
|
-
<span class='const'>RSpec</span><span class='op'>::</span><span class='const'>Expectations</span><span class='op'>::</span><span class='const'>ExpectationNotMetError</span>
|
375
|
-
<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>
|
376
|
-
<span class='const'>SystemStackError</span> <span class='const'>Psych</span><span class='op'>::</span><span class='const'>BadAlias</span>
|
377
367
|
</code></pre>
|
378
368
|
|
379
369
|
<p>While this is close to “Things that don’t descend from StandardError”, it’s not exactly that.</p>
|
@@ -386,7 +376,7 @@
|
|
386
376
|
<ul><li>
|
387
377
|
<p><strong>Info Level</strong>: Respects the skip list, excluding predefined sensitive or irrelevant variables. Global variables are ignored.</p>
|
388
378
|
</li><li>
|
389
|
-
<p><strong>Debug Level</strong>: Ignores the skip lists, capturing all variables including those typically excluded and global variables.
|
379
|
+
<p><strong>Debug Level</strong>: Ignores the skip lists, capturing all variables including those typically excluded and global variables. Global variables are only captured in debug mode, and they exclude the default Ruby global variables.</p>
|
390
380
|
</li></ul>
|
391
381
|
|
392
382
|
<p><strong>Default Behavior</strong>: By default, <code>info</code> level is used, which excludes variables in the skip list to protect sensitive information. In <code>debug</code> mode, the skip lists are ignored to provide more comprehensive data, which is useful during development but should be used cautiously to avoid exposing sensitive data. The info mode is recommended.</p>
|
@@ -460,7 +450,7 @@
|
|
460
450
|
<ul><li>
|
461
451
|
<p>EnhancedErrors won’t interrupt CI, but it lets me know what happened <em>without</em> reproduction steps</p>
|
462
452
|
</li><li>
|
463
|
-
<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>
|
464
454
|
</li><li>
|
465
455
|
<p>Has decent performance characteristics</p>
|
466
456
|
</li><li>
|
@@ -473,9 +463,9 @@
|
|
473
463
|
<ul><li>
|
474
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>
|
475
465
|
</li><li>
|
476
|
-
<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>
|
477
467
|
</li><li>
|
478
|
-
<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>
|
479
469
|
</li></ul>
|
480
470
|
|
481
471
|
<h2 id="label-Contributing">Contributing</h2>
|
@@ -491,9 +481,9 @@
|
|
491
481
|
</div></div>
|
492
482
|
|
493
483
|
<div id="footer">
|
494
|
-
Generated on
|
484
|
+
Generated on Wed Dec 25 13:01:48 2024 by
|
495
485
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
496
|
-
0.9.37 (ruby-3.1
|
486
|
+
0.9.37 (ruby-3.4.1).
|
497
487
|
</div>
|
498
488
|
|
499
489
|
</div>
|
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,21 +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><li>
|
205
|
-
<p>LLM-food - Feed debug info with variables into an LLM, making state examine-able for it</p>
|
206
|
-
</li></ul>
|
207
|
-
|
208
209
|
<h2 id="label-Installation">Installation</h2>
|
209
210
|
|
210
211
|
<p>Add this line to your <code>Gemfile</code>:</p>
|
@@ -269,13 +270,6 @@
|
|
269
270
|
<p>Terminal Color output: Enabled</p>
|
270
271
|
</li></ul>
|
271
272
|
</li><li>
|
272
|
-
<p><strong>Production</strong>:</p>
|
273
|
-
<ul><li>
|
274
|
-
<p>Output format: <code>:json</code></p>
|
275
|
-
</li><li>
|
276
|
-
<p>Terminal Color output: Disabled</p>
|
277
|
-
</li></ul>
|
278
|
-
</li><li>
|
279
273
|
<p><strong>CI Environment</strong>:</p>
|
280
274
|
<ul><li>
|
281
275
|
<p>Output format: <code>:plaintext</code></p>
|
@@ -370,10 +364,6 @@
|
|
370
364
|
<p>These exceptions are always ignored:</p>
|
371
365
|
|
372
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>
|
373
|
-
<span class='const'>ScriptError</span> <span class='const'>LoadError</span> <span class='const'>NotImplementedError</span> <span class='const'>SyntaxError</span>
|
374
|
-
<span class='const'>RSpec</span><span class='op'>::</span><span class='const'>Expectations</span><span class='op'>::</span><span class='const'>ExpectationNotMetError</span>
|
375
|
-
<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>
|
376
|
-
<span class='const'>SystemStackError</span> <span class='const'>Psych</span><span class='op'>::</span><span class='const'>BadAlias</span>
|
377
367
|
</code></pre>
|
378
368
|
|
379
369
|
<p>While this is close to “Things that don’t descend from StandardError”, it’s not exactly that.</p>
|
@@ -386,7 +376,7 @@
|
|
386
376
|
<ul><li>
|
387
377
|
<p><strong>Info Level</strong>: Respects the skip list, excluding predefined sensitive or irrelevant variables. Global variables are ignored.</p>
|
388
378
|
</li><li>
|
389
|
-
<p><strong>Debug Level</strong>: Ignores the skip lists, capturing all variables including those typically excluded and global variables.
|
379
|
+
<p><strong>Debug Level</strong>: Ignores the skip lists, capturing all variables including those typically excluded and global variables. Global variables are only captured in debug mode, and they exclude the default Ruby global variables.</p>
|
390
380
|
</li></ul>
|
391
381
|
|
392
382
|
<p><strong>Default Behavior</strong>: By default, <code>info</code> level is used, which excludes variables in the skip list to protect sensitive information. In <code>debug</code> mode, the skip lists are ignored to provide more comprehensive data, which is useful during development but should be used cautiously to avoid exposing sensitive data. The info mode is recommended.</p>
|
@@ -460,7 +450,7 @@
|
|
460
450
|
<ul><li>
|
461
451
|
<p>EnhancedErrors won’t interrupt CI, but it lets me know what happened <em>without</em> reproduction steps</p>
|
462
452
|
</li><li>
|
463
|
-
<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>
|
464
454
|
</li><li>
|
465
455
|
<p>Has decent performance characteristics</p>
|
466
456
|
</li><li>
|
@@ -473,9 +463,9 @@
|
|
473
463
|
<ul><li>
|
474
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>
|
475
465
|
</li><li>
|
476
|
-
<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>
|
477
467
|
</li><li>
|
478
|
-
<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>
|
479
469
|
</li></ul>
|
480
470
|
|
481
471
|
<h2 id="label-Contributing">Contributing</h2>
|
@@ -491,9 +481,9 @@
|
|
491
481
|
</div></div>
|
492
482
|
|
493
483
|
<div id="footer">
|
494
|
-
Generated on
|
484
|
+
Generated on Wed Dec 25 13:01:48 2024 by
|
495
485
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
496
|
-
0.9.37 (ruby-3.1
|
486
|
+
0.9.37 (ruby-3.4.1).
|
497
487
|
</div>
|
498
488
|
|
499
489
|
</div>
|
@@ -130,9 +130,9 @@
|
|
130
130
|
</div>
|
131
131
|
|
132
132
|
<div id="footer">
|
133
|
-
Generated on
|
133
|
+
Generated on Wed Dec 25 13:01:48 2024 by
|
134
134
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
135
|
-
0.9.37 (ruby-3.1
|
135
|
+
0.9.37 (ruby-3.4.1).
|
136
136
|
</div>
|
137
137
|
|
138
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.6"
|
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_errors.rb
CHANGED
@@ -9,7 +9,7 @@ module Enhanced; end
|
|
9
9
|
# Exceptions we could handle but overlook for other reasons. These class constants are not always loaded
|
10
10
|
# and generally are only be available when `required`, so we detect them by strings.
|
11
11
|
IGNORED_EXCEPTIONS = %w[RSpec::Expectations::ExpectationNotMetError RSpec::Matchers::BuiltIn::RaiseError
|
12
|
-
JSON::ParserError Zlib::Error OpenSSL::SSL::SSLError Psych::
|
12
|
+
JSON::ParserError Zlib::Error OpenSSL::SSL::SSLError Psych::BadAlias]
|
13
13
|
|
14
14
|
class EnhancedErrors
|
15
15
|
extend ::Enhanced
|
@@ -171,6 +171,7 @@ class EnhancedErrors
|
|
171
171
|
end
|
172
172
|
|
173
173
|
def override_exception_message(exception, binding_or_bindings)
|
174
|
+
return unless exception_is_handleable?(exception)
|
174
175
|
variable_str = EnhancedErrors.format(binding_or_bindings)
|
175
176
|
message_str = exception.message
|
176
177
|
exception.define_singleton_method(:unaltered_message) { message_str }
|
@@ -277,13 +278,14 @@ class EnhancedErrors
|
|
277
278
|
@rspec_tracepoint&.disable
|
278
279
|
@rspec_tracepoint = TracePoint.new(:raise) do |tp|
|
279
280
|
return unless exception_is_handleable?(tp.raised_exception)
|
280
|
-
|
281
|
-
case class_name
|
281
|
+
case tp.raised_exception.class.name
|
282
282
|
when 'RSpec::Expectations::ExpectationNotMetError'
|
283
283
|
start_rspec_binding_trap
|
284
284
|
else
|
285
285
|
handle_tracepoint_event(tp)
|
286
286
|
end
|
287
|
+
rescue => e
|
288
|
+
puts "Error in RSpec biding capture #{e} #{e.backtrace}"
|
287
289
|
end
|
288
290
|
end
|
289
291
|
@rspec_tracepoint&.enable
|
@@ -554,6 +556,7 @@ class EnhancedErrors
|
|
554
556
|
|
555
557
|
binding_context = tp.binding
|
556
558
|
method_name = tp.method_id
|
559
|
+
receiver = binding_context.receiver
|
557
560
|
|
558
561
|
locals = {}
|
559
562
|
|
@@ -567,7 +570,6 @@ class EnhancedErrors
|
|
567
570
|
}
|
568
571
|
|
569
572
|
instances = {}
|
570
|
-
receiver = binding_context.receiver
|
571
573
|
|
572
574
|
begin
|
573
575
|
if safe_to_inspect?(receiver)
|
@@ -635,8 +637,11 @@ class EnhancedErrors
|
|
635
637
|
Thread.current[:enhanced_errors_processing] = false
|
636
638
|
end
|
637
639
|
|
640
|
+
# Specifically avoid psych, and system level libraries, or libraries where variable context isn't
|
641
|
+
# likely to be particularly helpful or relevant.
|
638
642
|
def ignored_exception?(exception)
|
639
|
-
|
643
|
+
name = exception.class.name
|
644
|
+
IGNORED_EXCEPTIONS.include?(name) || name =~ /^(Gem|Psych|Zlib|OpenSSL|DRb|Prism|Reline|Fiddle)::/
|
640
645
|
end
|
641
646
|
|
642
647
|
def test_name
|
@@ -822,6 +827,10 @@ class EnhancedErrors
|
|
822
827
|
end
|
823
828
|
|
824
829
|
def exception_is_handleable?(exception)
|
830
|
+
exception && processable_exception?(exception) && !ignored_exception?(exception)
|
831
|
+
end
|
832
|
+
|
833
|
+
def processable_exception?(exception)
|
825
834
|
case exception
|
826
835
|
when SystemExit, SignalException, SystemStackError, NoMemoryError
|
827
836
|
# Non-actionable: Ignore these exceptions
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
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.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eric Beland
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date: 2024-12-
|
10
|
+
date: 2024-12-26 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: awesome_print
|
@@ -69,7 +68,6 @@ dependencies:
|
|
69
68
|
description: 'EnhancedErrors will automatically enhance your errors with messages
|
70
69
|
containing variable values from the moment they were raised, using no extra dependencies,
|
71
70
|
and only Ruby''s built-in TracePoint. '
|
72
|
-
email:
|
73
71
|
executables: []
|
74
72
|
extensions: []
|
75
73
|
extra_rdoc_files: []
|
@@ -125,7 +123,6 @@ licenses: []
|
|
125
123
|
metadata:
|
126
124
|
homepage_uri: https://github.com/ericbeland/enhanced_errors
|
127
125
|
source_code_uri: https://github.com/ericbeland/enhanced_errors
|
128
|
-
post_install_message:
|
129
126
|
rdoc_options: []
|
130
127
|
require_paths:
|
131
128
|
- lib
|
@@ -140,8 +137,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
140
137
|
- !ruby/object:Gem::Version
|
141
138
|
version: '0'
|
142
139
|
requirements: []
|
143
|
-
rubygems_version: 3.
|
144
|
-
signing_key:
|
140
|
+
rubygems_version: 3.6.2
|
145
141
|
specification_version: 4
|
146
142
|
summary: Automatically enhance your errors with messages containing variable values
|
147
143
|
from the moment they were raised.
|