Skip to content

Commit 31398b3

Browse files
hsbtclaude
andcommitted
Use Exception#detailed_message hook for lazy loading error enhancer gems
Prepend an Exception::DetailedMessage module on Exception that lazily loads error_highlight, did_you_mean, and syntax_suggest on first detailed_message call. Before loading, check whether any gem has already prepended detailed_message above us in the MRO (e.g. via -r flag). After loading and removing the hook method: - If gems were already above: use super (they already ran) - If gems were just loaded: re-dispatch via detailed_message(...) so their newly-prepended methods participate Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 538c28b commit 31398b3

1 file changed

Lines changed: 23 additions & 6 deletions

File tree

gem_prelude.rb

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,31 @@ def self.load
3636
warn "`syntax_suggest' was not loaded."
3737
end if defined?(SyntaxSuggest)
3838
end
39+
end
3940

41+
module Exception::DetailedMessage # :nodoc:
4042
def detailed_message(...)
41-
return super if Ruby::DetailedError.loaded?
42-
Ruby::DetailedError.load
43-
# Re-dispatch to pick up the newly prepended methods from the gems
44-
detailed_message(...)
43+
# Check if any gem has already prepended detailed_message
44+
# above us in the MRO (e.g. loaded via -r flag).
45+
gem_already_above = self.class.ancestors.take_while { |mod|
46+
mod != Exception::DetailedMessage
47+
}.any? { |mod| mod.method_defined?(:detailed_message, false) }
48+
49+
if defined?(Ruby::DetailedError)
50+
Ruby::DetailedError.load
51+
end
52+
Exception::DetailedMessage.remove_method(:detailed_message)
53+
54+
if gem_already_above
55+
# Gems already ran their detailed_message (they called
56+
# super to reach us). Just forward to Exception.
57+
super
58+
else
59+
# Gems were just loaded. Re-dispatch so their
60+
# newly-prepended methods run.
61+
detailed_message(...)
62+
end
4563
end
4664
end
47-
48-
Exception.prepend(Ruby::DetailedError)
65+
Exception.prepend(Exception::DetailedMessage)
4966
end

0 commit comments

Comments
 (0)