Airbrake fix
After installing airbrake gem my collection’s request Rspec.specs stoped working as expected.
I encounterd this error:
RuntimeError: can't add a new key into hash during iteration
Since Ruby 1.9(.3?) you cant modify Hash within iteration (even if they are ordered).
After some hours spent in debugger, I found that airbrake gem Notification
class uses Rack request @env
variable to collect params for aibrake/errbit notification.
Nothing weird here, but while collecting params in a loop , the clean_params
method hit the racks request’s @env
with the #cookies
method, in order to obtain the cookie hash. Code below :
def cookies
@env= @env.dup
hash = @env["rack.request.cookie_hash"] ||= {}
string = @env["HTTP_COOKIE"]
return hash if string == @env["rack.request.cookie_string"]
hash.clear
# According to RFC 2109:
# If multiple cookies satisfy the criteria above, they are ordered in
# the Cookie header such that those with more specific Path attributes
# precede those with less specific. Ordering with respect to other
# attributes (e.g., Domain) is unspecified.
cookies = Utils.parse_query(string, ';,') { |s| Rack::Utils.unescape(s) rescue s }
cookies.each { |k,v| hash[k] = Array === v ? v.first : v }
@env["rack.request.cookie_string"] = string
@env = env
hash
end
This method is available from the class Api (not private) and returns the cookie Hash, but it also have side effects …
Sadly, it mutates the @env
. I can’t say if this is bad design or not, but it looks weird to mee.
In order to get this working I submitted a fix to airbrake, not to Rack … Last words, thanks to ThoughBot guys, for all the opensource tools they provide, and reactivity to merge contribs.