-
Notifications
You must be signed in to change notification settings - Fork 205
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for passing options to JSON.parse #156
Conversation
I notice the build is failing for Ruby 1.8.x, I saw in another issue that it was mentioned in 2016 that Faraday had dropped support for < 1.9 and that the middleware would follow suit, is this still the case? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @stefansedich and thanks for your PR.
I think we can achieve the same result in a cleaner and backward compatible way so please address the comments in my review before we proceed 👍
:create_additions => options[:create_additions], | ||
:object_class => options[:object_class], | ||
:array_class => options[:array_class] | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't look DRY, it would be better to simply pass options
as it is to JSON.parse
.
@@ -47,7 +47,7 @@ def process_response(env) | |||
def parse(body) | |||
if self.class.parser | |||
begin | |||
self.class.parser.call(body) | |||
self.class.parser.call(body, @options) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than passing the entire @options
hash, I would opt for deciding on a specific @options
key (we can call it parser_options
) to be passed to the parser.
This will make the call like:
self.class.parser.call(body, @options[:parser_options])
IMPORTANT: We should pass this parameter ONLY if it's provided. We might have people defining custom parser that doesn't accept the second parameter. In order to maintain backward compatibility we need to make the second parameter optional
response = process(body) | ||
expect(response.body).to be(result) | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After applying the other 2 changes, this test can be refactored using the new parser_options
option.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Um, is 1.8 complaining that the lines aren't:
allow(::JSON).to receive(:parse).with(body, options[:parser_options]) { result }
Sounds good! Will make the changes today. |
@iMacTia how does that look now? |
It looks much better now! Unless there's any specific reason for using it, of course! Finally, don't worry about ruby 1.8.7, we're not supporting it anymore on Faraday so we can just do the same here. I need to update travis tests for that though. |
No problems @iMacTia I have rolled that back to what it was too! |
Great, thanks @stefansedich 👍 |
No problems. if there is anything I can help out with let me know! |
Yup, period at end of line works but looks ugly IMO, if 1.8 is not
supported anyway I was happy to leave it behind in the dust.
…On Sun, Jul 2, 2017, 10:38 AM Olle Jonsson ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In spec/unit/parse_json_spec.rb
<#156 (comment)>
:
> + allow(::JSON).to receive(:parse)
+ .with(
+ body,
+ :max_nesting => options[:max_nesting],
+ :allow_nan => options[:allow_nan],
+ :symbolize_names => options[:symbolize_names],
+ :create_additions => options[:create_additions],
+ :object_class => options[:object_class],
+ :array_class => options[:array_class]
+ )
+ .and_return(result)
+
+ response = process(body)
+ expect(response.body).to be(result)
+ end
+ end
Um, is 1.8 complaining that the lines aren't:
allow(::JSON).to receive(:parse).with(body, options[:parser_options]) { result }
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#156 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAIqVKZF-nkk3txeJbwXh2fW_wnTSs5zks5sJ9WXgaJpZM4N13EC>
.
|
@stefansedich can you please pull/rebase from master? |
@iMacTia done, funny thing is just the other day I was sitting there thinking to myself "I wish the middleware would let me pass in symbolize_names", I completely forgot I even had this PR sitting there 😄 |
Totally my fault there, it took me too much getting on this! |
No problems at all!
…On Thu, Jul 27, 2017, 8:42 AM Mattia ***@***.***> wrote:
Totally my fault there, it took me too much getting on this!
LGTM
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#156 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAIqVF7M_uFQGcnegxsNLsvBiuDdIkpoks5sSK_0gaJpZM4N13EC>
.
|
@iMacTia @stefansedich This change is backwards incompatible. ::JSON.parse(body, parser_options || {}) |
Mmmmh strange, I'm quite sure we have a good test coverage there. |
FYI, I've just tried the following: conn = Faraday.new('https://jsonplaceholder.typicode.com') do |f|
f.response :json
f.adapter :net_http
end
res = conn.get('/posts/1') and it works perfectly. |
@iMacTia Sorry, I thought this was something easier to recreate. Looking at the code, it's possible to invoke the parser block without any options:
Which will then raise the error I mentioned:
I noticed it using a class that inherits from Now I'm not exactly sure how to write a standalone failing example yet, but let me know if you'd instead want me to open a separate issue once I have one. |
Ok, let me complicate this one: JSON::VERSION
#=> "2.1.0"
raw_body = "{\n \"userId\": 1,\n \"id\": 1,\n \"title\": \"blahblahblah\",\n \"body\": \"blahblahblah\"\n}"
JSON.parse(raw_body, nil)
#=> {"userId"=>1, "id"=>1, "title"=>"blahblahblah", "body"=>"blahblahblah"} So it appears that the restriction on the |
@iMacTia Interesting, I'm using Oj: 2.4.0 :002 > require 'json'
=> true
2.4.0 :003 > JSON::VERSION
=> "2.1.0"
2.4.0 :004 > JSON.parse("{}", nil)
=> {}
2.4.0 :005 > require 'oj'
=> true
2.4.0 :006 > Oj::VERSION
=> "3.3.2"
2.4.0 :007 > Oj.mimic_JSON()
=> JSON
2.4.0 :008 > JSON.parse("{}", nil)
ArgumentError: options must be a hash.
from (irb):15:in `parse' Didn't expect it to be incompatible with JSON, thanks for pointing it out. |
I will get a fix over for this sometime later today, just woke up and saw
this thread, looks like we want to just always pass at least an empty
options hash in.
- Stefan
…On Mon, Jul 31, 2017, 8:27 AM Bart Kopinski ***@***.***> wrote:
@iMacTia <https://github.com/imactia> Interesting, I'm using Oj:
2.4.0 :002 > require 'json'
=> true2.4.0 :003 > JSON::VERSION
=> "2.1.0"2.4.0 :004 > JSON.parse("{}", nil)
=> {}2.4.0 :005 > require 'oj'
=> true2.4.0 :006 > Oj::VERSION
=> "3.2.0"2.4.0 :007 > Oj.mimic_JSON()
=> JSON2.4.0 :008 > JSON.parse("{}", nil)ArgumentError: options must be a hash.
from (irb):15:in `parse'
Didn't expect it to be incompatible with JSON, thanks for pointing it out.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#156 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAIqVIzBkIjMEyFY8W76XrYwZA7Xx7GNks5sTfJvgaJpZM4N13EC>
.
|
Mistery solved! |
PR opened @iMacTia but GitHub seems to be having some fun at the moment! |
Also experiencing the issue @bartoszkopinski mentioned with slack-ruby-client upon upgrading faraday_middleware to latest. Also using OJ gem. |
@booleanbetrayal I'll try to review @stefansedich PR tomorrow and plan an hotfix release for this week. |
I will open the issue up over on OJ right now @iMacTia |
Thank you! |
LGTM! |
For future visitors. |
lostisland/faraday_middleware#156 since there `parser_options` is not defaulted to a Hash, `JSON.parse` bombs
lostisland/faraday_middleware#156 since there `parser_options` is not defaulted to a Hash, `JSON.parse` bombs
@@ -7,8 +7,8 @@ class ParseJson < ResponseMiddleware | |||
require 'json' unless defined?(::JSON) | |||
end | |||
|
|||
define_parser do |body| | |||
::JSON.parse body unless body.strip.empty? | |||
define_parser do |body, parser_options| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since you're introducing an argument and there are other things that rely on this, i think it'd be prudent to default the block argument to an empty hash. otherwise JSON.parse
will bomb with an error that options is not a hash
.
This should fix #124 and allow all options to be passed to JSON.parse, it felt best to pass the options to the parse proc instead of overriding the parse method which was my second option and looks to be the way that the multijson middleware does it (which I am also open to doing).
Passing the options to the proc should be a non breaking change as any existing parsing middleware will continue to work as before and if required they will have access to the options argument.