Open opensourceame opened 1 year ago
Thank you for reporting this @opensourceame, I totally agree this is surprising! Please take a look at this more detailed inspection of the two objects:
[19] pry(main)> Faraday::Response.new(status: 200, body: 'test')
=> #<Faraday::Response:0x0000000136195a78
@env=
#<struct Faraday::Env
method=nil,
request_body=nil,
url=nil,
request=nil,
request_headers=nil,
ssl=nil,
parallel_manager=nil,
params=nil,
response=nil,
response_headers=nil,
status=200,
reason_phrase=nil,
response_body="test">,
@on_complete_callbacks=[]>
[20] pry(main)>
[21] pry(main)> Faraday::Response.new(body: 'test', status: 200)
=> #<Faraday::Response:0x0000000116e26898
@env=
#<struct Faraday::Env
method=nil,
request_body="test",
url=nil,
request=nil,
request_headers=nil,
ssl=nil,
parallel_manager=nil,
params=nil,
response=nil,
response_headers=nil,
status=200,
reason_phrase=nil,
response_body=nil>,
@on_complete_callbacks=[]>
As you can see from above, body
is not an actual field in Faraday::Response
, but rather an alias for either request_body
or response_body
.
And this "dynamic aliasing" works based on status
: if status
is set, then we assume the response have been fetched and body
refers to response_body
. Otherwise, no response was fetched, so body
still refers to request_body
.
You can see that in how []
and []=
are implemented for Env
: https://github.com/lostisland/faraday/blob/main/lib/faraday/options/env.rb#L89-L105
When you generate the hashes in your examples, body
always refer to response_body
, because in both cases status
is set.
However, the former example sets response_body
, while the latter sets request_body
, hence the latter example shows body: nil
when you print it out.
Although really convoluted, I'd say this is expected behaviour, because of the nature of the body
alias.
Users of the library won't normally instantiate a Faraday::Response
because the adapter will do that for them.
Adapters, OTOH, are encouraged to use the save_response
method which takes care of this for them among other things.
The real surprise here is that Faraday::Response
accepts body
as an initializer parameter, I'd have thought that would raise an error (instead, we should use request_body
or response_body
explicitly).
I'm currently planning some work on those Struct
s which may solve this confusion, so I'll leave this issue open until then.
Thanks for your response @iMacTia. I'm creating the response manually to create a dummy response when I get a callback from a remote server, which is passed to Ruby code via a queue system. Is there a better way to do this than initialising a response object, as in my example?
Agreed that body should not be accepted as an init param. Looking forward to your improvements ;-)
Is there a better way to do this than initialising a response object, as in my example?
I don't have a good alternative to that to be honest, but if you use a response_body
key instead of body
, at least you shouldn't have this issue anymore.
Basic Info
Issue description
When creating a
Faraday::Response
the body of the response is nullified if the status argument is specified after the body. This very unexpected behaviour.Steps to reproduce
works as expected:
body is nullified: