When working with external APIs, we often find ourselves tiptoeing around unpredictable behavior, timeouts, missing data, or malformed responses. In such cases, the goal is not always to raise an exception, but to fail gracefully and move on to the next fallback option.
In this post, we’ll examine a common pattern for safely extracting data from a JSON API response in Ruby without raising errors and explore how to make it clean, readable, and maintainable.
def fetch_coords_from_api
api_url = "some_api_url"
params = { api_key: ENV["API_KEY"] }
response = ApiClient.new(api_url, params).get
return nil unless response&.body
json = parse_json(response.body)
return nil unless json.is_a?(Hash)
addresses = json["result"]
return nil unless addresses.is_a?(Array) && addresses.any?
address = addresses.find { |add| add["zip"] == zip }
return nil unless address
lat = address["latitude"]
lng = address["longitude"]
lat && lng ? [lat, lng] : nil
end
private
def parse_json(body)
JSON.parse(body)
rescue JSON::ParserError
nil
end
We avoid NoMethodError by using response&.body, which prevents calling .body on nil.
We isolate the potentially dangerous JSON.parse in its own method and rescue JSON::ParserError internally, keeping the main method clean.
We use return nil unless for fast exits, keeping the method linear and readable.
We ensure the method only returns either a [latitude, longitude] array or nil, never a half-complete or broken object.
Work with our skilled Ruby on Rails developers to accelerate your project and boost its performance.
Hire Ruby on Rails Developer