I used to have a working code in my Admin Panel , checking if a url inputed existed and giving a friendly message to the Administrator in case it did not..
def get_url_response(url)
uri = URI(url)
request = Net::HTTP.get_response(uri)
return request
end
url_response = get_url_response("http://www.example.com").code
if url_response === "200" || url_response === "304"
link_to http://www.example.com, http://www.example.com, target: :blank
else
status_tag("We have a problem ! Response code: "+url_response, :class => 'red')
end
It works great when the address ("http://www.example.com" in the example above) exists, that it to say sends back a 200 code, but as soon as I have a non existing address such as http://www.examplenotexistingotallyfake.com, it should send a 404 code and display ""We have a problem ! Response code:" but it fails with the error message:
SocketError: Failed to open TCP connection to examplenotexistingotallyfake.com:443 (getaddrinfo: Name or service not known)
from /home/mreisner/.rvm/rubies/ruby-2.3.1/lib/ruby/2.3.0/net/http.rb:882:in `rescue in block in connect'
I verified this by opening my Rails console (Rails c) and if I type:
Net::HTTP.get(URI('https://www.examplenotexistingotallyfake.com')).code
I get the same error message:
SocketError: Failed to open TCP connection to examplenotexistingotallyfake.com:443 (getaddrinfo: Name or service not known)
from /home/mreisner/.rvm/rubies/ruby-2.3.1/lib/ruby/2.3.0/net/http.rb:882:in `rescue in block in connect'
How can it work for correct urls and not for non-existing addreses? it should just work but send me back a 404 code, shouldn't it?
I can only see the upgrade to Ubutun 16.04 i made a few days ago, that might have tampered with some critical dns/localhost settings as the source of this issue but not 100% totally sure.
EDIT
After some suggestions, I now try to avoid the app crashing by rescuing this
def get_url_response(url)
begin
uri = URI(url)
request = Net::HTTP.get_response(uri)
return request
rescue SocketError => e
puts "Got socket error: #{e}"
end
end
but the app still crashes with a socket Error message
That's the correct behaviour.
The problem there is that examplenotexistingotallyfake.com
doesn't exists in the DNSs entries.
If you look at the description of what the 404: https://en.wikipedia.org/wiki/HTTP_404
to indicate that the client was able to communicate with a given server, but the server could not find what was requested.
So, in order to get the 404 code you'll need first to be able to communicate with the server in question.
You can double check this behaviour using chrome or even curl, visiting the following urls: examplenotexistingotallyfake.com or google.com/missing
Each will give a different result.
in curl:
$ curl -I examplenotexistingotallyfake.com
curl: (6) Could not resolve host: examplenotexistingotallyfake.com
# google
curl -I google.com/missing
HTTP/1.1 404 Not Found
Content-Type: text/html; charset=UTF-8
Referrer-Policy: no-referrer
Content-Length: 1568
Date: Fri, 12 Jan 2018 09:25:27 GMT
If you want your code to behave in the same way (even though I'd suggest that give the user a different message, you can do the following):
require 'uri'
require 'net/http'
require 'ostruct'
def get_url_response(url)
uri = URI(url)
request = Net::HTTP.get_response(uri)
return request
rescue Errno::ECONNREFUSED => e
OpenStruct.new(code: 404)
end