Feature #21960
openImprove #backtrace to not confuse terminals
Description
The #backtrace of exceptions are currently printed like so:
/path/to/whatever.rb:8:in `/'
/path/to/whatever.rb:8:in `show'
(...)
Most terminals recognize /path/to/whatever.rb:8 as a local file and make it clickable as "open in editor", however, some (e.g. Ghostty) include everything up to the next whitespace, in this case /path/to/whatever.rb:8:in. This is then used as an argument to open (on macOS) which will not work due to the :in part.
There are two ways to improve this:
Replace the colon with a space¶
Given the existence of #backtrace_locations which is better suited for programmatically working with backtrace locations, it should not break things to slightly modify the #backtrace to look like this:
/path/to/whatever.rb:8 in `/'
/path/to/whatever.rb:8 in `show'
(...) ^^^
space instead of colon
Add OCS 8 sequences¶
OCS 8 are the <a> tag for terminal output. While many terminals support it, it might cause visual noise in logs and therefore would have to be an opt-in feature e.g. via a Ruby interpreter argument.
Updated by byroot (Jean Boussier) 1 day ago
- Related to Feature #14145: Proposal: Better Method#inspect added
Updated by byroot (Jean Boussier) 1 day ago
- Tracker changed from Misc to Feature
I believe this would be a good change, we did make a similar decision to use spaces over other symbols in [Feature #14145], so that it's easier to select.
This however has some small backward compatibly consequences, as code parsing backtraces with regexps isn't that rare.
That being said, most of the time, this sort of code would be much better to use backtrace_locations instead, one downside however is that in rare cases, some exceptions do have a #backtrace but no #backtrace_locations.
Updated by Eregon (Benoit Daloze) 1 day ago
+1, also I think it reads better with a space.
Re #14145 the motivation to use a space was also to be clickable: https://bugs.ruby-lang.org/issues/14145#note-25
FWIW your example in the description is using older backtrace, they look like this since 3.4:
$ ruby -ve 'tap { raise }'
ruby 4.0.1 (2026-01-13 revision e04267a14b) +PRISM [x86_64-linux]
-e:1:in 'block in <main>': unhandled exception
from -e:1:in 'Kernel#tap'
from -e:1:in '<main>'
Updated by svoop (Sven Schwyn) about 19 hours ago
@Eregon (Benoit Daloze) You're right, my bad, I happened to be on a project which still runs on Ruby 3.1. However, the colon is present on Ruby 4.0 as well:
path/to/test.rb:1:in 'Integer#/': divided by 0 (ZeroDivisionError)
from path/to/test.rb:1:in '<main>'
Updated by vo.x (Vit Ondruch) about 18 hours ago
This however has some small backward compatibly consequences, as code parsing backtraces with regexps isn't that rare.
That being said, most of the time, this sort of code would be much better to use backtrace_locations instead
This is typically not the case for test suites, unfortunately
Updated by byroot (Jean Boussier) about 18 hours ago
This is typically not the case for test suites
I'm not 100% sure I understand what you mean.
But yes, this change would certainly require to update a bunch of test there and there, just like when we changed labels to use single quotes intead of backticks.
Updated by byroot (Jean Boussier) about 18 hours ago
- Related to Feature #16495: Inconsistent quotes in error messages added
Updated by vo.x (Vit Ondruch) about 4 hours ago
byroot (Jean Boussier) wrote in #note-6:
I'm not 100% sure I understand what you mean.
When the backticks were changed, I have seen more broken test suites then the actual code. And the test suites typically checks error text output, probably by matching plain text or some RegExp. And I think that is very reasonable method for such test. Anything beyond that might be over engineered and prone to different issues.
Updated by svoop (Sven Schwyn) about 4 hours ago
From my POV, some failing tests which are easy enough to find and fix are no deal breaker though, albeit other people's mileage may vary. Problematic is (untested) code failing in production which is not very likely in this case and would point to a bigger code smell at large.