You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

升级Ubuntu16.04后Ruby2.3/Rails的Net::URI无法处理无效URL

Fixing SocketError When Checking Invalid URLs in Rails Admin Panel

Hey there! Let's break down why your code is still crashing even after adding exception handling, and how to fix it properly.

The Root Cause

First, let's clarify: a 404 status code is something a server returns when it can't find the requested resource. But when you use a totally fake domain like http://www.examplenotexistingotallyfake.com, the problem happens much earlier—your system can't even resolve the domain to an IP address via DNS. That's why you get a SocketError instead of a 404. Net::HTTP never gets to send a request to a server, so there's no HTTP status code to grab.

What's Wrong With Your Current Fix?

Your modified get_url_response method catches the SocketError, but after logging the error, it doesn't return anything (implicitly returns nil). Later, when your code tries to call .code on the result of get_url_response, you'll get a new error: undefined method 'code' for nil:NilClass—which is why your app still crashes.

The Proper Solution

We need to:

  1. Catch all likely network-related exceptions (not just SocketError).
  2. Return a consistent structure that your downstream code can safely use, even when an error occurs.

Here's a revised version of your code:

Step 1: Update the get_url_response Method

def get_url_response(url)
  uri = URI(url)
  request = Net::HTTP.get_response(uri)
  # Return a hash with success details
  { status_code: request.code, error: nil }
rescue SocketError, Timeout::Error, Errno::ECONNREFUSED, Net::HTTPBadResponse => e
  # Handle DNS failures, timeouts, connection refusals, and invalid responses
  { status_code: "503", error: "Network error: #{e.message}" }
rescue => e
  # Catch any other unexpected errors as a fallback
  { status_code: "500", error: "Unexpected error: #{e.message}" }
end

Step 2: Update the Calling Code

url_result = get_url_response("http://www.examplenotexistingotallyfake.com")
if ["200", "304"].include?(url_result[:status_code])
  link_to "http://www.example.com", "http://www.example.com", target: :blank
else
  error_message = "We have a problem! Response code: #{url_result[:status_code]}. #{url_result[:error]}"
  status_tag(error_message, class: 'red')
end

Why This Works

  • Comprehensive Exception Handling: We catch all common network issues that can prevent a request from completing, not just DNS failures.
  • Consistent Return Structure: The method always returns a hash with status_code and error keys, so your downstream code never tries to call methods on nil.
  • Clear Error Messaging: The admin gets specific details about what went wrong, not just a generic failure.

Checking Your DNS Configuration

If you still suspect your Ubuntu 16.04 DNS changes are causing issues, test this in your terminal:

ping examplenotexistingotallyfake.com

If it returns unknown host, your DNS is working correctly (it's properly identifying that the domain doesn't exist). If you get a different error (like timeouts without the "unknown host" message), then you might need to check your /etc/resolv.conf or network settings.

内容的提问来源于stack exchange,提问作者Mathieu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:00:51