ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
From: "ioquatix (Samuel Williams)" <noreply@ruby-lang.org>
To: ruby-core@ruby-lang.org
Subject: [ruby-core:105478] [Ruby master Bug#18194] No easy way to format exception messages per thread/fiber scheduler context.If you like, I can ask my contacts at several different APM companies to give their opinion too.
Date: Wed, 29 Sep 2021 00:42:29 +0000 (UTC)	[thread overview]
Message-ID: <redmine.journal-93927.20210929004229.3344@ruby-lang.org> (raw)
In-Reply-To: redmine.issue-18194.20210926204451.3344@ruby-lang.org

Issue #18194 has been updated by ioquatix (Samuel Williams).

Subject changed from No easy way to format exception messages per thread/fiber scheduler context. to No easy way to format exception messages per thread/fiber scheduler context.If you like, I can ask my contacts at several different APM companies to give their opinion too.

You think it's an advantage to change the default exception message to include additional formatted details. But I'm not so sure about that. Another way of looking at it is because there are other APMs consuming this information, such a change may be unexpected/incompatible.

Let's take Honeybadger as an example. They deduplicate errors by class and message. I don't know their exact algorithm, but including extra information in the `Exception#message` may cause them to incorrectly deduplicate errors. Changes in the loaded files might change `did_you_mean` output.

Another example I can think of would be the performance impact. By default, `did_you_mean` implementation or source code highlighting might be computationally expensive (loading source code, etc). In a production environment this might not be desirable, or may not even be useful.

I think what's more important is an interface that makes sense. Ruby has no mechanism for formatting or catching top level exceptions, but this IS a critical feature for APMs, not only APMs but a lot of applications would like to provide better formatting for exceptions which bubble all the way up, either in a thread or globally.

I think having a top level hook for exceptions makes total sense.

e.g.

```
Exception.unhandled do |exception|
  $stderr.puts exception.formatted_message
end

# or

Exception.unhandled do |exception|
  $stdout.puts Terminal.format(exception)
end
```

Threads should defer to the main thread if otherwise unset.

With this in place, any kind of formatting becomes really trivial especially if we define hooks for it. APMs can either opt in, or we can even make it the default, e.g.

```
Exception.unhandled do |exception|
  $stdout.puts exception.full_message(highlight: $stdout.tty?)
end
```

For APMs, they can opt into the same formatting interface if they so desire. I think the assumption is `highlight: true` gives xterm256 control sequences, so even web applications can consume this and convert to HTML relatively easily.

Gems like `did_you_mean` or `error_highlighter` should extend `full_message` or we should have some internal interface with extension points, for example:

```
class Exception
  # The supplied message.
  def message
  end

  def format_summary(output)
    output.print(:title, self.class.name, ":")
    output.print(:message, self.message)
  end

  def format_backtrace(output)
    self.backtrace.each do |line|
      output.print(:backtrace, line)
    end
  end

  def format(output)
    format_summary(output)
    format_backtrace(output)
  end
end
```

My preference is to inject an output wrapper which can handle styling in a simple but generic way. It's better than trying to use control sequences because it naturally supports any kind of output format (text, log, json, html, etc).

----------------------------------------
Bug #18194: No easy way to format exception messages per thread/fiber scheduler context.If you like, I can ask my contacts at several different APM companies to give their opinion too.
https://bugs.ruby-lang.org/issues/18194#change-93927

* Author: ioquatix (Samuel Williams)
* Status: Open
* Priority: Normal
* Assignee: mame (Yusuke Endoh)
* Backport: 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN
----------------------------------------
In the new error highlighting gem, formatting exception messages appears to be per-process which is insufficiently nuanced for existing use cases.

As in:

```ruby
class TerminalColorFormatter
  def message_for(spot)
    # How do we know the output format here? Maybe it's being written to a log file?
    "..."
  end
end

ErrorHighlight.formatter = TerminalColorFormatter.new
```

But we won't know until the time we actually write the error message whether terminal codes are suitable or available. Or an error message might be formatted for both the terminal and a log file, which have different formatting requirements. There are many consumers of error messages an some of them produce text, or HTML, or JSON, etc.

Because of this design we are effectively forcing everyone to parse the default text output if they want to do any kind of formatting, which will ossify the format and make it impossible in practice for anyone to use anything but the default `ErrorHighlight.format`. For what is otherwise a really fantastic idea, this implementation concerns me greatly.

I would like us to consider introducing sufficient metadata on the exception object so that complete formatting can be implemented by an output layer (e.g. logger, terminal wrapper, etc). This allows the output layer to intelligently format the output in a suitable way, or capture the metadata to allow for processing elsewhere.

In addition, to simplify this general usage, we might like to introduce `Exception#formatted_message`.

In order to handle default formatting requirements, we need to provide a hook for formatting uncaught exceptions. This would be excellent for many different use cases (e.g. HoneyBadger type systems), and I suggest we think about the best interface. Probably a thread-local with some default global implementation makes sense... maybe even something similar to `at_exit { ... $! ... }`.



-- 
https://bugs.ruby-lang.org/

  parent reply	other threads:[~2021-09-29  0:42 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-26 20:44 [ruby-core:105428] [Ruby master Bug#18194] No easy way to format exception messages per thread/fiber scheduler context ioquatix (Samuel Williams)
2021-09-26 20:57 ` [ruby-core:105429] " ioquatix (Samuel Williams)
2021-09-27  3:55 ` [ruby-core:105434] " ioquatix (Samuel Williams)
2021-09-27  4:07 ` [ruby-core:105437] " ioquatix (Samuel Williams)
2021-09-27  8:02 ` [ruby-core:105442] " mame (Yusuke Endoh)
2021-09-27 10:12 ` [ruby-core:105448] " Eregon (Benoit Daloze)
2021-09-27 10:53 ` [ruby-core:105449] " mame (Yusuke Endoh)
2021-09-27 22:01 ` [ruby-core:105456] " ioquatix (Samuel Williams)
2021-09-28  2:13 ` [ruby-core:105459] " mame (Yusuke Endoh)
2021-09-28  2:16 ` [ruby-core:105460] " ioquatix (Samuel Williams)
2021-09-28  2:26 ` [ruby-core:105461] " mame (Yusuke Endoh)
2021-09-29  0:42 ` ioquatix (Samuel Williams) [this message]
2021-09-29  0:43 ` [ruby-core:105479] " ioquatix (Samuel Williams)
2021-09-29  5:35 ` [ruby-core:105483] [Ruby master Feature#18194] " mame (Yusuke Endoh)
2021-09-29 10:10 ` [ruby-core:105486] " Eregon (Benoit Daloze)
2022-09-23  7:38 ` [ruby-core:110036] " ioquatix (Samuel Williams)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.ruby-lang.org/en/community/mailing-lists/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=redmine.journal-93927.20210929004229.3344@ruby-lang.org \
    --to=ruby-core@ruby-lang.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).