Class: EnhancedErrors
- Inherits:
-
Object
- Object
- EnhancedErrors
- Defined in:
- lib/enhanced_errors.rb
Overview
The EnhancedErrors class provides mechanisms to enhance exception handling by capturing additional context such as binding information, variables, and method arguments when exceptions are raised. It offers customization options for formatting and filtering captured data.
Constant Summary collapse
- GEMS_REGEX =
Regular expression to identify gem paths.
%r{[\/\\]gems[\/\\]}
- DEFAULT_MAX_LENGTH =
The default maximum length for formatted exception messages.
2500
- RSPEC_SKIP_LIST =
A set of RSpec-specific instance variables to skip.
Set.new([ :@fixture_cache, :@fixture_cache_key, :@fixture_connection_pools, :@connection_subscriber, :@saved_pool_configs, :@loaded_fixtures, :@matcher_definitions, ])
- RAILS_SKIP_LIST =
A set of Rails-specific instance variables to skip.
Set.new([ :@new_record, :@attributes, :@association_cache, :@readonly, :@previously_new_record, :@destroyed, :@marked_for_destruction, :@destroyed_by_association, :@primary_key, :@strict_loading, :@strict_loading_mode, :@mutations_before_last_save, :@mutations_from_database ])
Class Attribute Summary collapse
-
.capture_let_variables(value = nil) ⇒ Boolean
Gets or sets whether to capture RSpec ‘let` variables.
-
.config_block ⇒ Proc?
The configuration block provided during enhancement.
-
.eligible_for_capture {|exception| ... } ⇒ Proc
Sets or retrieves the eligibility criteria for capturing exceptions.
-
.enabled ⇒ Boolean
Indicates whether EnhancedErrors is enabled.
-
.max_length(value = nil) ⇒ Integer
Gets or sets the maximum length for the formatted exception message.
-
.on_capture_hook ⇒ Proc?
Hook to modify binding information upon capture.
-
.skip_list ⇒ Set<Symbol>
Retrieves the current skip list, initializing it with default values if not already set.
-
.trace ⇒ TracePoint?
The TracePoint object used for tracing exceptions.
Class Method Summary collapse
-
.add_to_skip_list(*vars) ⇒ Set<Symbol>
Adds variables to the skip list to exclude them from binding information.
-
.apply_skip_list(binding_info) ⇒ Hash
Applies the skip list to the captured binding information, excluding specified variables.
-
.binding_info_string(binding_info) ⇒ String
Formats a single binding information hash into a string with colorization.
-
.binding_infos_array_to_string(captured_bindings, format = :terminal) ⇒ String
Converts an array of binding information hashes into a formatted string.
-
.default_skip_list ⇒ Set<Symbol>
Initializes the default skip list by merging Rails and RSpec specific variables.
-
.enhance!(enabled: true, debug: false, capture_events: default_capture_events, **options) {|void| ... } ⇒ void
Enhances the exception handling by setting up tracing and configuration options.
-
.format(captured_bindings = [], output_format = get_default_format_for_environment) ⇒ String
Formats the captured binding information into a string based on the specified format.
-
.get_default_format_for_environment ⇒ Symbol
Determines the default output format based on the current environment.
-
.on_capture {|binding_info| ... } ⇒ Proc
Sets or retrieves the hook to modify binding information upon capture.
-
.on_capture=(value) ⇒ Proc
Sets the on_capture hook.
-
.on_format {|formatted_string| ... } ⇒ Proc
Sets or retrieves the hook to modify formatted exception messages.
-
.on_format=(value) ⇒ Proc
Sets the on_format hook.
-
.running_in_ci? ⇒ Boolean
Checks if the code is running in a Continuous Integration (CI) environment.
-
.validate_binding_format(binding_info) ⇒ Hash?
Validates the format of the captured binding information.
Class Attribute Details
.capture_let_variables(value = nil) ⇒ Boolean
Gets or sets whether to capture RSpec ‘let` variables.
55 56 57 |
# File 'lib/enhanced_errors.rb', line 55 def capture_let_variables @capture_let_variables end |
.config_block ⇒ Proc?
The configuration block provided during enhancement.
40 41 42 |
# File 'lib/enhanced_errors.rb', line 40 def config_block @config_block end |
.eligible_for_capture {|exception| ... } ⇒ Proc
Sets or retrieves the eligibility criteria for capturing exceptions.
60 61 62 |
# File 'lib/enhanced_errors.rb', line 60 def eligible_for_capture @eligible_for_capture end |
.enabled ⇒ Boolean
Indicates whether EnhancedErrors is enabled.
30 31 32 |
# File 'lib/enhanced_errors.rb', line 30 def enabled @enabled end |
.max_length(value = nil) ⇒ Integer
Gets or sets the maximum length for the formatted exception message.
45 46 47 |
# File 'lib/enhanced_errors.rb', line 45 def max_length @max_length end |
.on_capture_hook ⇒ Proc?
Hook to modify binding information upon capture.
50 51 52 |
# File 'lib/enhanced_errors.rb', line 50 def on_capture_hook @on_capture_hook end |
.skip_list ⇒ Set<Symbol>
Retrieves the current skip list, initializing it with default values if not already set.
65 66 67 |
# File 'lib/enhanced_errors.rb', line 65 def skip_list @skip_list end |
.trace ⇒ TracePoint?
The TracePoint object used for tracing exceptions.
35 36 37 |
# File 'lib/enhanced_errors.rb', line 35 def trace @trace end |
Class Method Details
.add_to_skip_list(*vars) ⇒ Set<Symbol>
Adds variables to the skip list to exclude them from binding information.
153 154 155 |
# File 'lib/enhanced_errors.rb', line 153 def add_to_skip_list(*vars) skip_list.merge(vars) end |
.apply_skip_list(binding_info) ⇒ Hash
Applies the skip list to the captured binding information, excluding specified variables.
327 328 329 330 331 332 333 334 335 |
# File 'lib/enhanced_errors.rb', line 327 def apply_skip_list(binding_info) unless @debug variables = binding_info[:variables] variables[:instances]&.reject! { |var, _| skip_list.include?(var) || (var.to_s.start_with?('@_') && !@debug) } variables[:locals]&.reject! { |var, _| skip_list.include?(var) } variables[:globals]&.reject! { |var, _| skip_list.include?(var) } end binding_info end |
.binding_info_string(binding_info) ⇒ String
Formats a single binding information hash into a string with colorization.
353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 |
# File 'lib/enhanced_errors.rb', line 353 def binding_info_string(binding_info) capture_event = binding_info[:capture_event].to_s.capitalize result = "#{Colors.red(capture_event)}: #{Colors.blue(binding_info[:source])}" result += method_and_args_desc(binding_info[:method_and_args]) variables = binding_info[:variables] || {} if variables[:locals] && !variables[:locals].empty? result += "\n#{Colors.green('Locals:')}\n#{variable_description(variables[:locals])}" end instance_vars_to_display = variables[:instances] || {} if instance_vars_to_display && !instance_vars_to_display.empty? result += "\n#{Colors.green('Instances:')}\n#{variable_description(instance_vars_to_display)}" end if variables[:lets] && !variables[:lets].empty? result += "\n#{Colors.green('Let Variables:')}\n#{variable_description(variables[:lets])}" end if variables[:globals] && !variables[:globals].empty? result += "\n#{Colors.green('Globals:')}\n#{variable_description(variables[:globals])}" end if result.length > max_length result = result[0...max_length] + "... (truncated)" end result + "\n" rescue => e # we swallow and don't re-raise to avoid any recursion problems. We don't want to # mess up the original exception handling. puts "EnhancedErrors error in binding_info_string: #{e.} #{e.backtrace}" return '' end |
.binding_infos_array_to_string(captured_bindings, format = :terminal) ⇒ String
Converts an array of binding information hashes into a formatted string.
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 |
# File 'lib/enhanced_errors.rb', line 269 def binding_infos_array_to_string(captured_bindings, format = :terminal) case format when :json Colors.enabled = false JSON.pretty_generate(captured_bindings) when :plaintext Colors.enabled = false captured_bindings.map { |binding_info| binding_info_string(binding_info) }.join("\n") when :terminal Colors.enabled = true captured_bindings.map { |binding_info| binding_info_string(binding_info) }.join("\n") else Colors.enabled = false captured_bindings.map { |binding_info| binding_info_string(binding_info) }.join("\n") end end |
.default_skip_list ⇒ Set<Symbol>
Initializes the default skip list by merging Rails and RSpec specific variables.
145 146 147 |
# File 'lib/enhanced_errors.rb', line 145 def default_skip_list Set.new(RAILS_SKIP_LIST).merge(RSPEC_SKIP_LIST) end |
.enhance!(enabled: true, debug: false, capture_events: default_capture_events, **options) {|void| ... } ⇒ void
This method returns an undefined value.
Enhances the exception handling by setting up tracing and configuration options.
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
# File 'lib/enhanced_errors.rb', line 164 def enhance!(enabled: true, debug: false, capture_events: default_capture_events, **, &block) capture_events = Array(capture_events) @output_format = nil @eligible_for_capture = nil @original_global_variables = nil if enabled == false @original_global_variables = nil @enabled = false @trace.disable if @trace else @enabled = true @debug = debug @original_global_variables = global_variables validate_and_set_capture_events(capture_events) .each do |key, value| setter_method = "#{key}=" if respond_to?(setter_method) send(setter_method, value) elsif respond_to?(key) send(key, value) else # Ignore unknown options or handle as needed end end @config_block = block_given? ? block : nil instance_eval(&@config_block) if @config_block start_tracing end end |
.format(captured_bindings = [], output_format = get_default_format_for_environment) ⇒ String
Formats the captured binding information into a string based on the specified format.
254 255 256 257 258 259 260 261 262 |
# File 'lib/enhanced_errors.rb', line 254 def format(captured_bindings = [], output_format = get_default_format_for_environment) result = binding_infos_array_to_string(captured_bindings, output_format) if @on_format_hook result = @on_format_hook.call(result) else result = default_on_format(result) end result end |
.get_default_format_for_environment ⇒ Symbol
Determines the default output format based on the current environment.
289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 |
# File 'lib/enhanced_errors.rb', line 289 def get_default_format_for_environment return @output_format unless @output_format.nil? env = ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development' @output_format = case env when 'development', 'test' if running_in_ci? :plaintext else :terminal end when 'production' :json else :terminal end end |
.on_capture {|binding_info| ... } ⇒ Proc
Sets or retrieves the hook to modify binding information upon capture.
213 214 215 216 217 218 219 |
# File 'lib/enhanced_errors.rb', line 213 def on_capture(&block) if block_given? @on_capture_hook = block else @on_capture_hook ||= method(:default_on_capture) end end |
.on_capture=(value) ⇒ Proc
Sets the on_capture hook.
225 226 227 |
# File 'lib/enhanced_errors.rb', line 225 def on_capture=(value) self.on_capture_hook = value end |
.on_format {|formatted_string| ... } ⇒ Proc
Sets or retrieves the hook to modify formatted exception messages.
233 234 235 236 237 238 239 |
# File 'lib/enhanced_errors.rb', line 233 def on_format(&block) if block_given? @on_format_hook = block else @on_format_hook ||= method(:default_on_format) end end |
.on_format=(value) ⇒ Proc
Sets the on_format hook.
245 246 247 |
# File 'lib/enhanced_errors.rb', line 245 def on_format=(value) @on_format_hook = value end |
.running_in_ci? ⇒ Boolean
Checks if the code is running in a Continuous Integration (CI) environment.
309 310 311 312 313 314 315 316 317 318 319 320 321 |
# File 'lib/enhanced_errors.rb', line 309 def running_in_ci? return @running_in_ci if defined?(@running_in_ci) ci_env_vars = { 'CI' => ENV['CI'], 'JENKINS' => ENV['JENKINS'], 'GITHUB_ACTIONS' => ENV['GITHUB_ACTIONS'], 'CIRCLECI' => ENV['CIRCLECI'], 'TRAVIS' => ENV['TRAVIS'], 'APPVEYOR' => ENV['APPVEYOR'], 'GITLAB_CI' => ENV['GITLAB_CI'] } @running_in_ci = ci_env_vars.any? { |_, value| value.to_s.downcase == 'true' } end |
.validate_binding_format(binding_info) ⇒ Hash?
Validates the format of the captured binding information.
341 342 343 344 345 346 347 |
# File 'lib/enhanced_errors.rb', line 341 def validate_binding_format(binding_info) unless binding_info.keys.include?(:capture_event) && binding_info[:variables].is_a?(Hash) puts "Invalid binding_info format." return nil end binding_info end |