crystal-lang

How can I silence or prevent a "Missing hash key" error?


I am getting a JSON response from an API, that I parse with JSON.parse(). I have a loop in my code that on each iteration checks if a certain parameter in the JSON response is equal to a defined string. This is a simpler version of the JSON response I am receiving:

{
  "response": [
    {
      "data": {
        "parameter": "value"
      }
    },
    {
      "data": {
        "parameter": "value2"
      }
    },
    {
      "data": {
        "parameter2": "value"
      }
    }
  ]
}

As you can see only response[0] and response[1] contain parameter. response[2] has parameter2. So if I loop through it with:

while i < responses.size
  response = responses[i]
  if(response.data.parameter == "value")
    *do something*
  end
end

I am gonna get Unhandled exception: Missing hash key: "parameter" when I get to the third iteration. Can I ignore or better, prevent the error from happening?


Solution

  • If you're correctly reading the data as an array of hashes of hashes, you can use has_key? to filter out invalid responses. The following sample code works for me:

    responses = {
      "response" => [
        {
          "data" => {
            "parameter" => "value",
          },
        },
        {
          "data" => {
            "parameter" => "value2",
          },
        },
        {
          "data" => {
            "parameter2" => "value",
          },
        },
      ],
    }
    
    pp responses
    
    responses["response"].each do |response|
      if response["data"].has_key?("parameter")
        pp response
        valid_response = response["data"]
        if valid_response["parameter"] == "value"
          puts "Doing something..."
        end
      end
    end
    

    and produces the following output:

    {"response" =>
      [{"data" => {"parameter" => "value"}},
       {"data" => {"parameter" => "value2"}},
       {"data" => {"parameter2" => "value"}}]}
    {"data" => {"parameter" => "value"}}
    Doing something...
    {"data" => {"parameter" => "value2"}}