Skip to content
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

fix(request): Handle edge cases in response parsing #29

Merged
merged 5 commits into from
Dec 21, 2023

Conversation

2k-joker
Copy link
Collaborator

What

Account for stuff like this:

NoMethodError: undefined method `with_indifferent_access' for []:Array

      JSON.parse(response_body).with_indifferent_access

Why

Not everyone designs proper json APIs

@2k-joker 2k-joker force-pushed the fix-bug-in-response-parsing branch from e302b43 to ed441a1 Compare December 21, 2023 17:53
@2k-joker 2k-joker merged commit 7818562 into main Dec 21, 2023
4 checks passed
@2k-joker 2k-joker deleted the fix-bug-in-response-parsing branch December 21, 2023 18:13
when Hash
parsed_body.with_indifferent_access
when Array
parsed_body.map(&:with_indifferent_access)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will still break in the case where the elements of the top-level array are themselves arrays or non-Object in general

for example, it would break on this valid json response in several different ways:

[
  {
    "foo": "bar"
  },
  1,
  "foobar",
  true,
  null,
  [
    {
      "inner": "object"
    },
    1,
    null,
    []
  ]
]

consider modifying the contract of the library to only return string-type json and thus eliminate this problem entirely -- simply don't try 😆

or, consider a safe recursive "deep with indifferent access." maybe something like this

def deep_with_indifferent_access(obj)
  case obj
  when Hash
    obj.each_with_object({}) do |(key, value), memo|
      memo[key] = deep_with_indifferent_access(value)
    end.with_indifferent_access
  when Array
    obj.map { |item| deep_with_indifferent_access(item) }
  else
    obj
  end
end

test = JSON.parse('[{"foo": "bar"},1,"foobar",true,null,[{"inner": "object"},1,null,[]]]')
result = deep_with_indifferent_access(test)
# => [{"foo"=>"bar"}, 1, "foobar", true, nil, [{"inner"=>"object"}, 1, nil, []]]

result[0][:foo]
# => "bar"

result[5][0][:inner]
# => "object"

note: the deep recursion implementation is probably bugged too 😅

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what the NoMethodError rescue is for hehe. "I tried to help but your thing is weird so I'm leaving it as-is, enjoy"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants