diff options
author | Kasumi Hanazuki <[email protected]> | 2023-11-28 23:05:26 +0900 |
---|---|---|
committer | git <[email protected]> | 2023-11-28 14:05:31 +0000 |
commit | 5fc71feb6ca8b62d51f9b6421cb26c9f1228be17 (patch) | |
tree | 557b2e130bc76d182a8bd93391f9686167c60122 | |
parent | 9365b78d49bfee1a1b40d02c7f6ac8b3a9954b8d (diff) |
[ruby/irb] Rescue errors from main.to_s/inspect when formatting
prompt
(https://github.com/ruby/irb/pull/791)
Currently, IRB just terminates if `main.to_s` raises while IRB
constructs the prompt string. This can easily happen if the user wants
to start an IRB session in the instance scope of an uninitialized
object, for example:
```
class C
def initialize
binding.irb
@values = []
end
def to_s = @values.join(',') # raises if uninitialized
end
C.new
```
This patch makes IRB rescue from such an exception and displays the
class name of the exception instead of `main.to_s` to indicate some
error has occurred.
We may display more detailed information about the exception, but this
patch chooses not to do so because 1) the prompt has limited space,
2) users can evaluate `to_s` in IRB to examine the error if they want,
and 3) obtaining the details can also raise, which requires nested
exception handling and can be complicated.
https://github.com/ruby/irb/commit/412ab26067
-rw-r--r-- | lib/irb.rb | 6 | ||||
-rw-r--r-- | test/irb/test_context.rb | 9 |
2 files changed, 13 insertions, 2 deletions
diff --git a/lib/irb.rb b/lib/irb.rb index 8c3039482e..66149eb455 100644 --- a/lib/irb.rb +++ b/lib/irb.rb @@ -930,9 +930,11 @@ module IRB when "N" @context.irb_name when "m" - truncate_prompt_main(@context.main.to_s) + main_str = @context.main.to_s rescue "!#{$!.class}" + truncate_prompt_main(main_str) when "M" - truncate_prompt_main(@context.main.inspect) + main_str = @context.main.inspect rescue "!#{$!.class}" + truncate_prompt_main(main_str) when "l" ltype when "i" diff --git a/test/irb/test_context.rb b/test/irb/test_context.rb index ce57df6cdb..5804607d13 100644 --- a/test/irb/test_context.rb +++ b/test/irb/test_context.rb @@ -631,6 +631,15 @@ module TestIRB assert_equal('irb("aaaaaaaaaaaaaaaaaaaaaaaaaaaa...)>', irb.send(:format_prompt, 'irb(%M)>', nil, 1, 1)) end + def test_prompt_main_raise + main = Object.new + def main.to_s; raise TypeError; end + def main.inspect; raise ArgumentError; end + irb = IRB::Irb.new(IRB::WorkSpace.new(main), TestInputMethod.new) + assert_equal("irb(!TypeError)>", irb.send(:format_prompt, 'irb(%m)>', nil, 1, 1)) + assert_equal("irb(!ArgumentError)>", irb.send(:format_prompt, 'irb(%M)>', nil, 1, 1)) + end + def test_lineno input = TestInputMethod.new([ "\n", |