I have partial solution for this issue:
Check the external file headers. The app is sending a header request to the external server.
1.1 If the status is 200 (success), then the app starts the retrieve process as before.
1.2 If the status is any other value, then an error page is displayed with the appropriate error message.
 
And the code looks like this:
uri = URI.parse(link)
net_http = Net::HTTP.new(uri.host, uri.port)
net_http.open_timeout = options[:timeout]
net_http.read_timeout = options[:timeout]
net_http.use_ssl = (uri.scheme == 'https')
if net_http.use_ssl?
  net_http.cert = OpenSSL::X509::Certificate.new(File.read(options[:cert]))
  net_http.key = OpenSSL::PKey::RSA.new(File.read(options[:cert]))
  net_http.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
begin
  request = Net::HTTP::Get.new(uri.request_uri)
  res = net_http.request(request)
  if res.code.to_i == 200
    self.response.headers['Pragma'] = 'no-cache'
    self.response.headers['Cache-Control'] = 'private,max-age=0,must-revalidate,no-store'
    self.response.headers['Last-Modified'] = Time.now.ctime.to_s
    self.response.headers['Accept-Ranges'] = 'bytes'
    self.response.headers['Content-Type'] = type
    self.response.headers['Content-Disposition'] = "attachment; filename=\"#{save_as}\""
    self.response.headers['Content-Transfer-Encoding'] = 'binary'
    self.response.headers['Content-Description'] = 'File Transfer'
    self.response.headers['Content-Length'] = "#{filesize}"
    self.response_body = FileStreamer.new(link, options)
  else
    raise "The requested file is not available at the moment"
  end
rescue SocketError => se
  raise 'It seems the URL is not correct'
rescue Errno::ECONNREFUSED => cr
  raise 'It seems the server refused the connection request'
rescue Errno::EHOSTUNREACH => hu
  raise 'It seems the server cannot be reached'
rescue Errno::ENETUNREACH => nu
  raise 'It seems the network cannot be reached'
rescue Timeout::Error => te
  raise 'Request timed out while connecting to the server'
rescue StandardError => e
  raise e.message
end
The FileStreamer is a rack middleware which response to each method.
def each
  begin
    @net_http.start do |http|
      http.request_get(@uri.request_uri(), 
        {'User-Agent' => 'FileStreamer'}) do |response|
        case response
          when Net::HTTPSuccess then
            response.read_body do |segment|
              yield segment
            end
          when Net::HTTPRedirection then
            raise 'Redirection not allowed'
          else
            raise "Error trying to retrieve a file:\n" \
              "  URL: #{@uri.to_s}\n" \
              "  Error: #{response.message.to_s}"
        end
      end
    end
  rescue SocketError => se
    raise 'It seems the URL is not correct'
  rescue Errno::ECONNREFUSED => cr
    raise 'It seems the server refused the connection request'
  rescue Errno::EHOSTUNREACH => hu
    raise 'It seems the server cannot be reached'
  rescue Errno::ENETUNREACH => nu
    raise 'It seems the network cannot be reached'
  rescue Timeout::Error => te
    raise 'Request timed out while connecting to the server'
  rescue StandardError => e
    raise e.message
  end
end
Keep in mind this solution is not including errors happening in the middle of the process, I guess if an error happens in the middle, then the app will display the ugly error page.