irb icon indicating copy to clipboard operation
irb copied to clipboard

IRB exits with "undefined method `split' for nil:NilClass (NoMethodError)" on empty #to_s definition in exceptions

Open mschnitzer opened this issue 5 years ago • 1 comments

Hi,

I just stumbled over an issue where my application raised an exception and due to a corner case in my Rails app, the exception class had an empty #to_s block.

class MyTestException < Exception
  def to_s; end
end

When this exception is raised in an IRB session, IRB fails with the following error:

Traceback (most recent call last):
        5: from (irb):1
        4: from app/lib/pushover_api/message.rb:9:in `push'
        3: from app/lib/pushover_api/request.rb:35:in `send'
        2: from app/lib/pushover_api/request.rb:54:in `validate_response!'
        1: from (byebug):1:in `validate_response!'
Traceback (most recent call last):
	30: from bin/rails:4:in `<main>'
	29: from /usr/lib64/ruby/gems/2.5.0/gems/activesupport-6.0.2.1/lib/active_support/dependencies.rb:325:in `require'
	28: from /usr/lib64/ruby/gems/2.5.0/gems/activesupport-6.0.2.1/lib/active_support/dependencies.rb:291:in `load_dependency'
	27: from /usr/lib64/ruby/gems/2.5.0/gems/activesupport-6.0.2.1/lib/active_support/dependencies.rb:325:in `block in require'
	26: from /usr/lib64/ruby/gems/2.5.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
	25: from /usr/lib64/ruby/gems/2.5.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:21:in `require_with_bootsnap_lfi'
	24: from /usr/lib64/ruby/gems/2.5.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
	23: from /usr/lib64/ruby/gems/2.5.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `block in require_with_bootsnap_lfi'
	22: from /usr/lib64/ruby/gems/2.5.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require'
	21: from /usr/lib64/ruby/gems/2.5.0/gems/railties-6.0.2.1/lib/rails/commands.rb:18:in `<top (required)>'
	20: from /usr/lib64/ruby/gems/2.5.0/gems/railties-6.0.2.1/lib/rails/command.rb:46:in `invoke'
	19: from /usr/lib64/ruby/gems/2.5.0/gems/railties-6.0.2.1/lib/rails/command/base.rb:69:in `perform'
	18: from /usr/lib64/ruby/gems/2.5.0/gems/thor-1.0.1/lib/thor.rb:392:in `dispatch'
	17: from /usr/lib64/ruby/gems/2.5.0/gems/thor-1.0.1/lib/thor/invocation.rb:127:in `invoke_command'
	16: from /usr/lib64/ruby/gems/2.5.0/gems/thor-1.0.1/lib/thor/command.rb:27:in `run'
	15: from /usr/lib64/ruby/gems/2.5.0/gems/railties-6.0.2.1/lib/rails/commands/console/console_command.rb:102:in `perform'
	14: from /usr/lib64/ruby/gems/2.5.0/gems/railties-6.0.2.1/lib/rails/commands/console/console_command.rb:19:in `start'
	13: from /usr/lib64/ruby/gems/2.5.0/gems/railties-6.0.2.1/lib/rails/commands/console/console_command.rb:70:in `start'
	12: from /usr/lib64/ruby/2.5.0/irb.rb:383:in `start'
	11: from /usr/lib64/ruby/2.5.0/irb.rb:427:in `run'
	10: from /usr/lib64/ruby/2.5.0/irb.rb:427:in `catch'
	 9: from /usr/lib64/ruby/2.5.0/irb.rb:428:in `block in run'
	 8: from /usr/lib64/ruby/2.5.0/irb.rb:487:in `eval_input'
	 7: from /usr/lib64/ruby/2.5.0/irb/ruby-lex.rb:231:in `each_top_level_statement'
	 6: from /usr/lib64/ruby/2.5.0/irb/ruby-lex.rb:231:in `catch'
	 5: from /usr/lib64/ruby/2.5.0/irb/ruby-lex.rb:232:in `block in each_top_level_statement'
	 4: from /usr/lib64/ruby/2.5.0/irb/ruby-lex.rb:232:in `loop'
	 3: from /usr/lib64/ruby/2.5.0/irb/ruby-lex.rb:246:in `block (2 levels) in each_top_level_statement'
	 2: from /usr/lib64/ruby/2.5.0/irb.rb:488:in `block in eval_input'
	 1: from /usr/lib64/ruby/2.5.0/irb.rb:623:in `signal_status'
/usr/lib64/ruby/2.5.0/irb.rb:530:in `block (2 levels) in eval_input': undefined method `split' for nil:NilClass (NoMethodError)

Well, it's not a blocker for me, I just make sure that the exception returns at least an empty string to bypass this issue.

mschnitzer avatar Jan 05 '20 13:01 mschnitzer

Hmm, I think this crash is based on a complicated application environment according to the backtrace. I can't reproduce it.

By the way, Ruby 2.5 bundles IRB 0.9.6. It's too old. Could you try to add gem 'irb' to Gemfile of your application and run bundle update? The latest IRB was drastically rewritten.

aycabta avatar Jan 05 '20 14:01 aycabta

Fixed in irb-1.10.0 https://github.com/ruby/irb/pull/780

irb(main):001* class MyTestException < Exception
irb(main):002*   def to_s; end
irb(main):003*   raise self
irb(main):004> end
#<MyTestException: #<MyTestException:0x0000000134336460>>
backtraces are hidden because undefined method `encoding' for nil was raised when processing them
irb(main):005> 

tompng avatar Aug 14 '24 17:08 tompng