Ruby处理不符合预期的不同JSON响应问题
Fixing Your Ruby Carrier Lookup Script to Handle API Errors
Hey there! Let's get that script stabilized so it doesn't crash when hitting invalid phone numbers. The core issue is that when the API returns an error response, you're trying to access json["Message360"]["Carrier"]—which doesn't exist—leading to a NoMethodError when you call .values on a nil value. We'll add proper error handling to either log errors or skip invalid entries, plus make the script more efficient overall.
Modified Script with Error Handling
Here's an updated version that handles both API error responses and unexpected exceptions, while logging errors to a separate file:
require 'csv' require 'uri' require 'net/http' require 'json' # Open output files once (more efficient than opening/closing per row) CSV.open("new.csv", "wb") do |results_csv| # Write header for successful results results_csv << ["ApiVersion", "CarrierSid", "AccountSid", "PhoneNumber", "Network", "Wireless", "ZipCode", "City", "Price", "Status", "DateCreated"] CSV.open("errors.csv", "wb") do |errors_csv| # Write header for error logs errors_csv << ["Original Number", "Error Code", "Error Message"] CSV.foreach('data1.csv', headers: true) do |row| raw_number = row['number'].strip # Optional: Auto-format to E164 (required by the API) formatted_number = "+1#{raw_number}" begin uri = URI("https://api.message360.com/api/v3/carrier/lookup.json?PhoneNumber=#{formatted_number}") req = Net::HTTP::Post.new(uri) req.basic_auth 'XXX', 'XXX' res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http| http.request(req) end # Parse the API response json = JSON.parse(res.body) message360 = json["Message360"] if message360["ResponseStatus"] == 1 # Success: Extract carrier data and write to results carrier_values = message360["Carrier"].values results_csv << carrier_values else # API returned an error: Log details error_details = message360["Errors"]["Error"].first errors_csv << [raw_number, error_details["Code"], error_details["Message"]] # Optional: Add error entry to main results file instead # results_csv << [nil, nil, nil, raw_number, "ERROR: #{error_details["Message"]}", nil, nil, nil, nil, "failed", nil] end rescue JSON::ParserError => e # Handle invalid JSON from the API errors_csv << [raw_number, "JSON_PARSE_FAILURE", "Could not parse API response: #{e.message}"] rescue NoMethodError => e # Handle missing keys in the API response errors_csv << [raw_number, "MISSING_RESPONSE_KEY", "API response missing expected data: #{e.message}"] rescue StandardError => e # Catch-all for other issues (network timeouts, auth failures, etc.) errors_csv << [raw_number, "GENERAL_ERROR", "Unexpected issue: #{e.message}"] end end end end
Key Improvements Explained
- Prevent Crashes with
begin/rescue: Wraps all API interaction and parsing logic in error handling blocks to catch and log exceptions instead of terminating the script. - Explicit Response Status Check: First checks
ResponseStatusto distinguish between successful and error responses, avoiding attempts to access non-existentCarrierdata. - Efficient File Handling: Opens output files once outside the loop instead of opening/closing them for every row, which speeds up processing.
- Error Logging: Writes invalid numbers and their error details to a dedicated
errors.csvfile for easy review. You can also uncomment the optional line to include error entries directly in your main results file. - E164 Formatting: Adds optional auto-formatting to the required North American E164 format (
+1XXXYYYZZZZ), which may reduce the number of invalid number errors in the first place.
Bonus Tips
- Avoid Hardcoded Credentials: Store your API username/password in environment variables instead of hardcoding them, e.g.,
req.basic_auth ENV['MESSAGE360_USER'], ENV['MESSAGE360_PASS']. - Rate Limiting: If processing a large CSV, add a small delay (like
sleep(0.5)) inside the loop to avoid hitting API rate limits. - Validate Inputs: Add a check to ensure each row's
numberis a valid 10-digit number before sending it to the API.
内容的提问来源于stack exchange,提问作者Alex T
相关产品推荐
相关产品推荐

