I discovered a mysterious ArgumentError when requiring 'openssl/cipher' instead of 'openssl' and initializing a OpenSSL::Cipher object. The ArgumentError does not indicate where the exception is being raised from.
Subject changed from ArgumentError with no backtrace when requiring openssl/cipher and initializing an OpenSSL::Cipher to ArgumentError with no backtrace information when requiring openssl/cipher and initializing an OpenSSL::Cipher
@Hanmac oh I am aware that require 'openssl' is the correct way to load all of openssl. The bug in question is that it causes an ArgumentError to be raised, but does not show where the exception is being raised from. That is confusing behavior to the end-user.
technically it does show, the problem are the parameter for initialize, or better for BasicObject#initialize
The Error you get is this one:
irb(main):001:0> class X
irb(main):002:0> end
=> nil
irb(main):003:0> x= X.new("abe")
(irb):3:in `initialize': wrong number of arguments (given 1, expected 0) (ArgumentError)
from (irb):3:in `new'
from (irb):3:in `<main>'
from C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/irb-1.4.1/exe/irb:11:in `<top (required)>'
from C:/Ruby31-x64/bin/irb:33:in `load'
from C:/Ruby31-x64/bin/irb:33:in `<main>'
because BasicObject#initialize doesn't want any Parameters
now when you require openssl/cipher you get a Cipher class using the default ruby alloc with the BasicObject#initialize
which of course is crashing when you give them any parameters
In terms of openssl/cipher, requiring individual parts of a library should never be assumed to be supported unless the library is explicitly designed for that. We shouldn't attempt to detect invalid requires and raise for them, in my opinion.
In terms of the error message, it shows the bug comes from #initialize. You could argue that is confusing because you don't know which #initialize, but if so, that's a general Ruby issue and not related to OpenSSL::Cipher. If you wanted to change that, we'd need to change the default backtrace format to show which method implementation was called (the owner/defined class of the method being called).