From: "Eregon (Benoit Daloze)" Date: 2021-11-11T11:38:33+00:00 Subject: [ruby-core:106028] [Ruby master Bug#18296] Custom exception formatting should override `Exception#full_message`. Issue #18296 has been updated by Eregon (Benoit Daloze). While initially thinking about this issue I kind of forgot `full_message` includes the backtrace (the name doesn't make that super obvious). One thing to address is how `did_you_mean/error_highlight` can insert additional output after the original message, but before the backtrace (for `order: :top` the default). `super(highlight: highlight, **options) + "\nextra"` wouldn't work as that would put it after the end of the backtrace. Also the backtrace can be before the message with `order: :bottom`. I think one possibility is: ```ruby module DidYouMean module Formatter def full_message(highlight: Exception.to_tty?, order: :top, backtrace: true, did_you_mean: true, **options) super if backtrace == :only || !did_you_mean message = super(highlight: highlight, **options, backtrace: false) backtrace = super(highlight: highlight, **options, backtrace: :only) if order == :top "#{message}\nextra stuff\n#{backtrace}" else "#{backtrace}#{message}\nextra stuff\n" end end end end Exception.prepend DidYouMean::Formatter ``` If we want to avoid the `if order == :top`, we'd need a new method that's basically the same as `full_message` but always without the backtrace, and that method would be called from `Exception#full_message` (needs at least the `highlight:` keyword, best to forward all keywords). (then we don't need the `backtrace:` kwarg for `full_message` of course) Like: ```ruby module DidYouMean module Formatter def message_with_extras(highlight: Exception.to_tty?, did_you_mean: true, **options) super unless did_you_mean message = super(highlight: highlight, **options) "#{message}\nextra stuff\n" end end end Exception.prepend DidYouMean::Formatter # And Exception#full_message would call #message_with_extras` and not #message. # The default Exception#message_with_extras just calls #message. ``` I'm not sure which is better, WDYT? Do we want to also have "message with extras" for causes' messages in the `full_message` output? If so the #message_with_extras approach seems better, because that's quite difficult to make it work with `full_message`. Of course `#message_with_extras` is just a name, maybe we can find a better one. (We could also add kwargs to Exception#message but that would be incompatible with all definitions of `message` which don't accept any argument, hence doesn't seem possible.) ---------------------------------------- Bug #18296: Custom exception formatting should override `Exception#full_message`. https://bugs.ruby-lang.org/issues/18296#change-94615 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal * Backport: 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN ---------------------------------------- After discussing with @eregon, we came to the conclusion that the current implementation of `did_you_mean` and `error_highlight` could avoid many issues by using `Exception#full_message`. We propose to introduce a more nuanced interface: ```ruby class Exception def full_message(highlight: bool, order: [:top or :bottom], **options) # ... end end module DidYouMean class Formatter def full_message(highlight:, did_you_mean: true, **options) buffer = super(highlight: highlight, **options).dup buffer << "extra stuff" end end end module ErrorHighlight class Formatter def full_message(highlight:, error_highlight: true, **options) # same as above end end end ``` -- https://bugs.ruby-lang.org/ Unsubscribe: