enhanced_errors 2.0.1 → 2.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardoc/checksums +4 -4
- data/.yardoc/object_types +0 -0
- data/.yardoc/objects/root.dat +0 -0
- data/doc/{Colors.html → Enhanced/Colors.html} +28 -28
- data/doc/Enhanced/Integrations/RSpecErrorFailureMessage.html +182 -0
- data/doc/Enhanced/Integrations.html +115 -0
- data/doc/{Binding.html → Enhanced.html} +26 -39
- data/doc/EnhancedErrors.html +998 -1332
- data/doc/Exception.html +251 -0
- data/doc/_index.html +28 -17
- data/doc/class_list.html +1 -1
- data/doc/file.README.html +116 -37
- data/doc/index.html +116 -37
- data/doc/method_list.html +83 -27
- data/doc/top-level-namespace.html +9 -26
- data/enhanced_errors.gemspec +1 -1
- data/lib/enhanced_errors.rb +28 -14
- metadata +7 -9
- data/doc/Debugging.html +0 -181
- data/doc/ErrorEnhancements.html +0 -258
- data/doc/images/enhance.png +0 -0
- data/doc/images/enhanced-error.png +0 -0
- data/doc/images/enhanced-spec.png +0 -0
data/doc/file.README.html
CHANGED
@@ -62,7 +62,7 @@
|
|
62
62
|
|
63
63
|
<h2 id="label-Overview">Overview</h2>
|
64
64
|
|
65
|
-
<p><strong>EnhancedErrors</strong> is a pure Ruby gem that enhances
|
65
|
+
<p><strong>EnhancedErrors</strong> is a pure Ruby gem that enhances exceptions by capturing variables and their values from the scope where the error was raised.</p>
|
66
66
|
|
67
67
|
<p><strong>EnhancedErrors</strong> leverages Ruby’s built-in <a href="https://ruby-doc.org/core-3.1.0/TracePoint.html">TracePoint</a> feature to provide detailed context for exceptions, making debugging easier without significant performance overhead.</p>
|
68
68
|
|
@@ -74,7 +74,10 @@
|
|
74
74
|
<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>
|
75
75
|
<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
|
76
76
|
</span>
|
77
|
-
<span class='
|
77
|
+
<span class='comment'># Enable capturing of variables at exception at raise-time. The .captured_variables method
|
78
|
+
</span><span class='comment'># is added to all Exceptions and gets populated with in-scope variables and values on `raise`
|
79
|
+
</span>
|
80
|
+
<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_enhance_exceptions!'><span class='object_link'><a href="EnhancedErrors.html#enhance_exceptions!-class_method" title="EnhancedErrors.enhance_exceptions! (method)">enhance_exceptions!</a></span></span>
|
78
81
|
|
79
82
|
<span class='kw'>def</span> <span class='id identifier rubyid_foo'>foo</span>
|
80
83
|
<span class='kw'>begin</span>
|
@@ -82,7 +85,7 @@
|
|
82
85
|
<span class='ivar'>@myinstance</span> <span class='op'>=</span> <span class='int'>10</span>
|
83
86
|
<span class='id identifier rubyid_foo'>foo</span> <span class='op'>=</span> <span class='ivar'>@myinstance</span> <span class='op'>/</span> <span class='id identifier rubyid_myvar'>myvar</span>
|
84
87
|
<span class='kw'>rescue</span> <span class='op'>=></span> <span class='id identifier rubyid_e'>e</span>
|
85
|
-
<span class='id identifier rubyid_puts'>puts</span> <span class='id identifier rubyid_e'>e</span><span class='period'>.</span><span class='id identifier
|
88
|
+
<span class='id identifier rubyid_puts'>puts</span> <span class='id identifier rubyid_e'>e</span><span class='period'>.</span><span class='id identifier rubyid_captured_variables'>captured_variables</span>
|
86
89
|
<span class='kw'>end</span>
|
87
90
|
<span class='kw'>end</span>
|
88
91
|
|
@@ -116,15 +119,57 @@
|
|
116
119
|
|
117
120
|
<p><img src=“./doc/images/enhanced-spec.png” style=“height: 369px; width: 712px;”></img></p>
|
118
121
|
|
122
|
+
<h1 id="label-RSpec+Setup">RSpec Setup</h1>
|
123
|
+
|
124
|
+
<p>The simplest way to get started with EnhancedErrors is to use it for RSpec exception capturing. To get variable output into RSpec, the approach below enables capturing, but also gives nice output by formatting the failure message with the variable capture.</p>
|
125
|
+
|
126
|
+
<p>The advantage of this approach is that it is only active for your spec runs. This approach is ideal for CI and local testing because it doesn’t make any changes that should bleed through to production–it doesn’t enhance exceptions except those that pass by during the RSpec run.</p>
|
127
|
+
|
128
|
+
<pre class="code ruby"><code class="ruby">
|
129
|
+
<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>
|
130
|
+
|
131
|
+
<span class='comment'># add these config changes to your RSpec config to get variable messages
|
132
|
+
</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'>:suite</span><span class='rparen'>)</span> <span class='kw'>do</span>
|
133
|
+
<span class='const'>RSpec</span><span class='op'>::</span><span class='const'>Core</span><span class='op'>::</span><span class='const'>Example</span><span class='period'>.</span><span class='id identifier rubyid_prepend'>prepend</span><span class='lparen'>(</span><span class='const'><span class='object_link'><a href="Enhanced.html" title="Enhanced (module)">Enhanced</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Enhanced/Integrations.html" title="Enhanced::Integrations (module)">Integrations</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Enhanced/Integrations/RSpecErrorFailureMessage.html" title="Enhanced::Integrations::RSpecErrorFailureMessage (module)">RSpecErrorFailureMessage</a></span></span><span class='rparen'>)</span>
|
134
|
+
<span class='kw'>end</span>
|
135
|
+
|
136
|
+
<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>
|
137
|
+
<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>
|
138
|
+
<span class='kw'>end</span>
|
139
|
+
|
140
|
+
<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>
|
141
|
+
<span class='id identifier rubyid_example'>example</span><span class='period'>.</span><span class='id identifier rubyid_metadata'>metadata</span><span class='lbracket'>[</span><span class='symbol'>:expect_binding</span><span class='rbracket'>]</span> <span class='op'>=</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>
|
142
|
+
<span class='kw'>end</span>
|
143
|
+
|
144
|
+
<span class='kw'>end</span>
|
145
|
+
</code></pre>
|
146
|
+
|
147
|
+
<h2 id="label-Minitest">Minitest</h2>
|
148
|
+
|
149
|
+
<p>Untested as of yet, but enhance_exceptions!(override_messages: true) is likely to work.</p>
|
150
|
+
|
151
|
+
<p>If anyone wants to look into an integration implementation like RSpec, it would be welcomed. With a more targeted approach like the RSpec one, exceptions could be captured and modified only during test time, like the RSpec approach. This would be advantageous as it wouldn’t modify the exception message itself, but still makes the variable output available in test messages.</p>
|
152
|
+
|
153
|
+
<h2 id="label-Enhancing+.message">Enhancing .message</h2>
|
154
|
+
|
155
|
+
<p>EnhancedErrors can also append the captured variable description into the Exception’s .message method output if the override_messages argument is true.</p>
|
156
|
+
|
157
|
+
<p>This can be very convenient as it lets you capture and diagnose the context of totally unanticipated exceptions without modifying all your error handlers.</p>
|
158
|
+
|
159
|
+
<p>The downside to this approach is that if you have expectations in your tests/specs around exception messages, those may break. Also, if you are doing something with the error messages, like storing them in a database, they could be <em>much</em> longer and that may pose an issue.</p>
|
160
|
+
|
161
|
+
<p>Ideally, use exception.captured_variables instead.</p>
|
162
|
+
|
163
|
+
<pre class="code ruby"><code class="ruby"><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_enhance_exceptions!'><span class='object_link'><a href="EnhancedErrors.html#enhance_exceptions!-class_method" title="EnhancedErrors.enhance_exceptions! (method)">enhance_exceptions!</a></span></span><span class='lparen'>(</span><span class='label'>override_messages:</span> <span class='kw'>true</span><span class='rparen'>)</span>
|
164
|
+
</code></pre>
|
165
|
+
|
119
166
|
<h2 id="label-Features">Features</h2>
|
120
167
|
<ul><li>
|
121
168
|
<p><strong>Pure Ruby</strong>: No external dependencies, C extensions, or C API calls.</p>
|
122
169
|
</li><li>
|
123
|
-
<p><strong>Lightweight</strong>: Minimal performance impact, as tracing is only active during exception raising.</p>
|
124
|
-
</li><li>
|
125
170
|
<p><strong>Customizable Output</strong>: Supports multiple output formats (<code>:json</code>, <code>:plaintext</code>, <code>:terminal</code>).</p>
|
126
171
|
</li><li>
|
127
|
-
<p><strong>Flexible Hooks</strong>: Redact or modifying captured data via the <code>on_capture</code> hook.</p>
|
172
|
+
<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>
|
128
173
|
</li><li>
|
129
174
|
<p><strong>Environment-Based Defaults</strong>: For Rails apps, automatically adjusts settings based on the environment (<code>development</code>, <code>test</code>, <code>production</code>, <code>ci</code>).</p>
|
130
175
|
</li><li>
|
@@ -135,25 +180,27 @@
|
|
135
180
|
<p><strong>Capture Types</strong>: Captures variables from the first <code>raise</code> and the last <code>rescue</code> for an exception by default.</p>
|
136
181
|
</li><li>
|
137
182
|
<p><strong>No dependencies</strong>: EnhancedErrors does not <strong><em>require</em></strong> any dependencies–it uses <a href="https://github.com/awesome-print/awesome_print">awesome_print</a> for nicer output if it is installed and available.</p>
|
183
|
+
</li><li>
|
184
|
+
<p><strong>Lightweight</strong>: Minimal performance impact, as tracing is only active during exception raising.</p>
|
138
185
|
</li></ul>
|
139
186
|
|
140
187
|
<p>EnhancedErrors has a few big use-cases:</p>
|
141
188
|
<ul><li>
|
142
189
|
<p><strong>Catch Data-driven bugs</strong>. For example, if, while processing a 10 gig file, you get an error, you can’t just re-run the code with a debugger. You also can’t just print out all the data, because it’s too big. You want to know what the data was the cause of the error. Ideally, without long instrument-re-run-fix loops. If your logging didn’t capture the data, normally, you’d be stuck.</p>
|
143
190
|
</li><li>
|
144
|
-
<p><strong>Debug</strong> a complex application erroring deep in the stack when you can’t tell where the error originates
|
191
|
+
<p><strong>Debug</strong> a complex application erroring deep in the stack when you can’t tell where the error originates.</p>
|
145
192
|
</li><li>
|
146
|
-
<p><strong>
|
193
|
+
<p><strong>Reduce MTTR</strong> Reduce mean time to resolution.</p>
|
147
194
|
</li><li>
|
148
195
|
<p><strong>Faster CI -> Fix loop</strong>. When a bug happens in CI, usually there’s a step where you first reproduce it locally. EnhancedErrors can help you skip that step.</p>
|
149
196
|
</li><li>
|
150
|
-
<p><strong>Faster
|
197
|
+
<p><strong>Faster TDD</strong>. In general, you can skip the add-instrumentation step and jump to the fix. Usually, you won’t have to re-run to see an error.</p>
|
151
198
|
</li><li>
|
152
199
|
<p><strong>Heisenbugs</strong> - bugs that disappear when you try to debug them. EnhancedErrors can help you capture the data that causes the bug before it disappears.</p>
|
153
200
|
</li><li>
|
154
201
|
<p><strong>Unknown Unknowns</strong> - you can’t pre-emptively log variables from failure cases you never imagined.</p>
|
155
202
|
</li><li>
|
156
|
-
<p><strong>Cron jobs</strong> and <strong>daemons</strong> - when it fails for unknown reasons at 4am, check the log and fix–it probably has what you need
|
203
|
+
<p><strong>Cron jobs</strong> and <strong>daemons</strong> - when it fails for unknown reasons at 4am, check the log and fix–it probably has what you need. Note that</p>
|
157
204
|
</li></ul>
|
158
205
|
|
159
206
|
<h2 id="label-Installation">Installation</h2>
|
@@ -175,24 +222,28 @@
|
|
175
222
|
|
176
223
|
<h2 id="label-Basic+Usage">Basic Usage</h2>
|
177
224
|
|
178
|
-
<p>To enable EnhancedErrors, call the <code>
|
225
|
+
<p>To enable EnhancedErrors, call the <code>enhance_exceptions!</code> method:</p>
|
179
226
|
|
180
|
-
<pre class="code ruby"><code class="ruby"><span class='comment'># For a rails app, put this in an initializer, or spec_helper.rb
|
181
|
-
</span><span class='comment'># ex: config/initializers/
|
182
|
-
</span
|
227
|
+
<pre class="code ruby"><code class="ruby"><span class='comment'># For a rails app, you may put this in an initializer, or spec_helper.rb
|
228
|
+
</span><span class='comment'># ex: config/initializers/enhanced.rb
|
229
|
+
</span><span class='comment'># you should immediately see nice errors with variables in your logs
|
230
|
+
</span>
|
183
231
|
<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
|
184
|
-
</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
|
232
|
+
</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_enhance_exceptions!'><span class='object_link'><a href="EnhancedErrors.html#enhance_exceptions!-class_method" title="EnhancedErrors.enhance_exceptions! (method)">enhance_exceptions!</a></span></span><span class='lparen'>(</span><span class='label'>override_messages:</span> <span class='kw'>true</span><span class='rparen'>)</span>
|
233
|
+
</code></pre>
|
234
|
+
|
235
|
+
<p>The approach above activates the TracePoint to start capturing exceptions and their surrounding context. It also overrides the .message to have the variables.</p>
|
185
236
|
|
186
|
-
<
|
187
|
-
</span></code></pre>
|
237
|
+
<p>If modifying your exception handlers is an option, it is better <em>not</em> to use override_messages: true, but instead just use the exception.captured_variables, which is a string describing what was found, that is available regardless.</p>
|
188
238
|
|
189
|
-
<p>
|
239
|
+
<p>Note that a minimalistic approach is taken to generating the string–if no qualifying variables were present, you won’t see any message!</p>
|
190
240
|
|
191
241
|
<h3 id="label-Configuration+Options">Configuration Options</h3>
|
192
242
|
|
193
|
-
<p>You can pass configuration options to <code>
|
243
|
+
<p>You can pass configuration options to <code>enhance_exceptions!</code>:</p>
|
194
244
|
|
195
|
-
<pre class="code ruby"><code class="ruby"
|
245
|
+
<pre class="code ruby"><code class="ruby">
|
246
|
+
<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_enhance_exceptions!'><span class='object_link'><a href="EnhancedErrors.html#enhance_exceptions!-class_method" title="EnhancedErrors.enhance_exceptions! (method)">enhance_exceptions!</a></span></span><span class='lparen'>(</span><span class='label'>enabled:</span> <span class='kw'>true</span><span class='comma'>,</span> <span class='label'>max_length:</span> <span class='int'>2000</span><span class='rparen'>)</span> <span class='kw'>do</span>
|
196
247
|
<span class='comment'># Additional configuration here
|
197
248
|
</span> <span class='id identifier rubyid_add_to_skip_list'>add_to_skip_list</span> <span class='symbol'>:@instance_variable_to_skip</span><span class='comma'>,</span> <span class='symbol'>:local_to_skip</span>
|
198
249
|
<span class='kw'>end</span>
|
@@ -202,7 +253,7 @@
|
|
202
253
|
</li><li>
|
203
254
|
<p><code>enabled</code>: Enables or disables the enhancement (default: <code>true</code>).</p>
|
204
255
|
</li><li>
|
205
|
-
<p><code>max_length</code>: Sets the maximum length of the
|
256
|
+
<p><code>max_length</code>: Sets the maximum length of the captured_variables string (default: <code>2500</code>).</p>
|
206
257
|
</li></ul>
|
207
258
|
|
208
259
|
<p>Currently, the first <code>raise</code> exception binding is presented. This may be changed in the future to allow more binding data to be presented.</p>
|
@@ -293,7 +344,7 @@
|
|
293
344
|
|
294
345
|
<h4 id="label-Using+on_format">Using <code>on_format</code></h4>
|
295
346
|
|
296
|
-
<p><code>on_format</code> is the last stop for the message string that will be
|
347
|
+
<p><code>on_format</code> is the last stop for the message string that will be <code>exception.captured_variables</code>.</p>
|
297
348
|
|
298
349
|
<p>Here it can be encrypted, rewritten, or otherwise modified.</p>
|
299
350
|
|
@@ -307,7 +358,7 @@
|
|
307
358
|
<p>EnhancedErrors comes with predefined skip lists to exclude sensitive or irrelevant variables. By default, the skip list is used to remove a lot of framework noise from Rails and RSpec. You can add additional variables to the skip list as needed:</p>
|
308
359
|
|
309
360
|
<pre class="code ruby"><code class="ruby">
|
310
|
-
<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
|
361
|
+
<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_enhance_exceptions!'><span class='object_link'><a href="EnhancedErrors.html#enhance_exceptions!-class_method" title="EnhancedErrors.enhance_exceptions! (method)">enhance_exceptions!</a></span></span> <span class='kw'>do</span>
|
311
362
|
<span class='id identifier rubyid_add_to_skip_list'>add_to_skip_list</span> <span class='symbol'>:@variable_to_skip</span>
|
312
363
|
<span class='kw'>end</span>
|
313
364
|
</code></pre>
|
@@ -318,15 +369,11 @@
|
|
318
369
|
|
319
370
|
<p>These exceptions are always ignored:</p>
|
320
371
|
|
321
|
-
<pre class="code ruby"><code class="ruby">SystemExit
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
LoadError,
|
327
|
-
NotImplementedError,
|
328
|
-
SyntaxError,
|
329
|
-
SystemStackError
|
372
|
+
<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>
|
330
377
|
</code></pre>
|
331
378
|
|
332
379
|
<p>While this is close to “Things that don’t descend from StandardError”, it’s not exactly that.</p>
|
@@ -353,7 +400,7 @@ SystemStackError
|
|
353
400
|
<p><strong><code>rescue</code></strong>: Captures the context when an exception is last rescued.</p>
|
354
401
|
</li></ul>
|
355
402
|
|
356
|
-
<p><strong>Default Behavior</strong>: By default, EnhancedErrors
|
403
|
+
<p><strong>Default Behavior</strong>: By default, EnhancedErrors starts with rescue capture off. The <code>rescue</code> exception is only available in Ruby 3.2+ as it was added to TracePoint events in Ruby 3.2. If enabled, it returns the first <code>raise</code> and the last <code>rescue</code> event for each exception.</p>
|
357
404
|
|
358
405
|
<h3 id="label-Example-3A+Redacting+Sensitive+Information">Example: Redacting Sensitive Information</h3>
|
359
406
|
|
@@ -385,7 +432,14 @@ SystemStackError
|
|
385
432
|
|
386
433
|
<p>The captured data includes a <code>capture_event</code> field indicating whether the data was captured during a <code>raise</code> or <code>rescue</code> event. By default, EnhancedErrors returns the first <code>raise</code> and the last <code>rescue</code> event for each exception, providing a clear trace of the exception lifecycle.</p>
|
387
434
|
|
388
|
-
<p>The captured data is
|
435
|
+
<p>The captured data is available in .captured_variables, to provide context for debugging.</p>
|
436
|
+
<ul><li>
|
437
|
+
<p>EnhancedErrors does not persist captured data--it only keep it in memory for the lifetime of the exception.</p>
|
438
|
+
</li><li>
|
439
|
+
<p>There are benchmarks around Tracepoint in the benchmark folder. Targeted tracepoints seem to be very cheap--as in, you can hit them ten thousand+ times a second without heavy overhead.</p>
|
440
|
+
</li></ul>
|
441
|
+
|
442
|
+
<p>*</p>
|
389
443
|
|
390
444
|
<h2 id="label-Awesome+Print">Awesome Print</h2>
|
391
445
|
|
@@ -394,11 +448,36 @@ SystemStackError
|
|
394
448
|
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_gem'>gem</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>awesome_print</span><span class='tstring_end'>'</span></span>
|
395
449
|
</code></pre>
|
396
450
|
|
451
|
+
<h2 id="label-Alternatives">Alternatives</h2>
|
452
|
+
|
453
|
+
<p>Why not use:</p>
|
454
|
+
|
455
|
+
<p><a href="https://github.com/banister/binding_of_caller">binding_of_caller</a> or <a href="https://github.com/pry/pry">Pry</a> or <a href="https://github.com/BetterErrors/better_errors">better_errors</a>?</p>
|
456
|
+
|
457
|
+
<p>First off, these gems are, I cannot stress this enough, a-m-a-z-i-n-g!!! I use them every day–kudos to their creators and maintainers!</p>
|
458
|
+
|
459
|
+
<p>This is intended for different use-cases. In sum, the goal of this gem is an every-day driver for <strong>non-interactive</strong> variable inspection.</p>
|
460
|
+
|
461
|
+
<p>With EnhancedErrors is that I want extra details when I run into a problem I <strong>didn’t anticipate ahead of time</strong>. To make that work, it has to be able to safely be ‘on’ all the time, and it has to gather the data in a way I naturally will see it without requiring extra preparation I obviously didn’t know to do.</p>
|
462
|
+
<ul><li>
|
463
|
+
<p>That won’t interrupt CI, but also, that lets me know what happened without reproduction</p>
|
464
|
+
</li><li>
|
465
|
+
<p>That could, theoretically, also be fine in production (if data security, redaction, access, and encryption concerns were all addressed–Ok, big list, but another option is to selectively enable targeted capture)</p>
|
466
|
+
</li><li>
|
467
|
+
<p>Has decent performance characteristics</p>
|
468
|
+
</li><li>
|
469
|
+
<p><strong>Only</strong> becomes active in exception raise/rescue scenarios</p>
|
470
|
+
</li></ul>
|
471
|
+
|
472
|
+
<p>This gem could have been implemented using binding_of_caller, or the gem it depends on, <a href="https://rubygems.org/gems/debug_inspector/versions/1.1.0?locale=en">debug_inspector</a>. However, the recommendation is not to use those in production as they use C API extensions. This doesn’t. This selectively uses Ruby’s TracePoint binding capture very narrowly with no other C API or dependencies, and only to target Exceptions–not to allow universal calls to the prior binding. It doesn’t work as a debugger, but that also means it can, with care, operate safely in a narrow scope–becoming active only when exceptions are raised.</p>
|
473
|
+
|
397
474
|
<h2 id="label-Performance+Considerations">Performance Considerations</h2>
|
398
475
|
<ul><li>
|
399
|
-
<p><strong>Minimal Overhead</strong>: Since TracePoint is only activated during exception raising and rescuing, the performance impact is negligible during normal operation
|
476
|
+
<p><strong>Minimal Overhead</strong>: Since TracePoint is only activated during exception raising and rescuing, the performance impact is negligible during normal operation. (Benchmark included)</p>
|
477
|
+
</li><li>
|
478
|
+
<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>
|
400
479
|
</li><li>
|
401
|
-
<p><strong>Production
|
480
|
+
<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>
|
402
481
|
</li></ul>
|
403
482
|
|
404
483
|
<h2 id="label-Contributing">Contributing</h2>
|
@@ -411,7 +490,7 @@ SystemStackError
|
|
411
490
|
</div></div>
|
412
491
|
|
413
492
|
<div id="footer">
|
414
|
-
Generated on
|
493
|
+
Generated on Mon Dec 9 19:51:26 2024 by
|
415
494
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
416
495
|
0.9.37 (ruby-3.1.3).
|
417
496
|
</div>
|