(This ticket is for recording the final spec of #18438)
I would introduce a method
Exception#detailed_message, and let the default error printer use it instead of
Exception#message to create a error output.
class MyClass < StandardError def message = "my error!" def detailed_message(highlight: false, **opt) super + "\nThis is\nan additional\nmessage" end end raise MyClass
$ ./miniruby test.rb test.rb:8:in `<main>': my error! (MyClass) This is an additional message
Here is the implementation: https://github.com/ruby/ruby/pull/5516
Exception#detailed_message(highlight: false) calls
#message and decorates the returned string. It may add the class name of exception and, when
highlight keyword is true, some escape sequences for highlights.
e = RuntimeError.new("my error!") p e.detailed_message #=> "my error! (RuntimeError)" p e.detailed_message(highlight: true) #=> "\e[1mmy error! (\e[1;4mRuntimeError\e[m\e[1m)\e[m"
Previously, the default error printer and
#message to get the error message, applied some processing (adding the error class name and adding escape sequences) to the string, and added backtrace. Now, they now use
#detailed_message(highlight: Exception.to_tty?) instead of
All keyword arguments passed to
Exception#full_message are delegated to
The primary motivation is a clean integration of did_you_mean and error_highlight gems.
At the present time, they overrides
Exception#to_s to add their suggestions. However, there are some known problems in this approach:
- It may break some tests to check the result of
Exception#to_sdepending on whether the gems add suggestions or not.
- Some Ruby scripts re-raise an exception by
raise e.class, e.message, e.backtrace, which makes the gems add their suggestion multiple times (currently, the gems ad-hocly check and avoid multiple addition).
- Sometimes a user needs to get the original message without their addition. For the sake, did_you_mean provides
Exception#original_message, but the workaround is not very well known.
This proposal allows the gems to override
Exception#to_s is kept as-is, so the above problems will no longer occur.
Also, the proposal allows a user to get a full_message without the suggestions by
err.full_message(did_you_mean: false, error_highlight: false).
Here is a proof-of-concept patch for did_you_mean and error_highlight: https://gist.github.com/mame/2c34230f11237dc4af64510cb98acdd8 I'll create PRs for the gems after
Exception#detailed_message is merged.
This change requires application monitoring services such as Sentry, DataDog, ScoutAPM, etc. They need to use
Exception#detailed_message(highlight: false) instead of
Exception#message to log the error messages after Ruby 3.2. Thankfully, @st0012 (Stan Lo) (the maintainer of Sentry's Ruby SDK) and @ivoanjo (Ivo Anjo) and @marcotc (Marco Costa) (the maintainers of Datadog's application monitoring gem) have agreed with this change.