diff --git a/app/models/ip_info.rb b/app/models/ip_info.rb index 707ef1a1..96a09e48 100644 --- a/app/models/ip_info.rb +++ b/app/models/ip_info.rb @@ -4,7 +4,11 @@ class IpInfo def initialize(ip_address) @ip_address = ip_address - @info = JSON.parse(Net::HTTP.get("ip-api.com", "/json/#{@ip_address}")) + Timeout::timeout(3) do + @info = JSON.parse(Net::HTTP.get("ip-api.com", "/json/#{@ip_address}")) + end + rescue Net::OpenTimeout, JSON::ParserError, Timeout::Error + @info = {} end def successful? diff --git a/spec/models/ip_info_spec.rb b/spec/models/ip_info_spec.rb index 81fbf161..0416004a 100644 --- a/spec/models/ip_info_spec.rb +++ b/spec/models/ip_info_spec.rb @@ -1,6 +1,25 @@ require 'rails_helper' RSpec.describe IpInfo, type: :model do + context "exceptions" do + let(:subject) { described_class.new("73.11.237.17") } + + it "is unsuccessful when the network times out" do + allow(Net::HTTP).to receive(:get).and_raise(Net::OpenTimeout) + expect(subject.successful?).to eq false + end + + it "is unsuccessful when the json is invalid" do + allow(Net::HTTP).to receive(:get).and_return("") # invalid JSON + expect(subject.successful?).to eq false + end + + it "is unsuccessful when the timeout is reached" do + allow(Net::HTTP).to receive(:get).and_raise(Timeout::Error) + expect(subject.successful?).to eq false + end + end + context "invalid ip addresses" do let(:subject) { described_class.new("invalid") }