class VCR::Errors::UnhandledHTTPRequestError

Error raised when an HTTP request is made that VCR is unable to handle. @note VCR will raise this to force you to do something about the

HTTP request. The idea is that you want to handle _every_ HTTP
request in your test suite. The error message will give you
suggestions for how to deal with the request.

Constants

ALL_SUGGESTIONS

List of suggestions for how to configure VCR to handle the request.

Attributes

request[R]

The HTTP request.

Public Class Methods

new(request) click to toggle source

Constructs the error.

@param [VCR::Request] request the unhandled request.

Calls superclass method
# File lib/vcr/errors.rb, line 70
def initialize(request)
  @request = request
  super construct_message
end

Private Instance Methods

cassettes_description() click to toggle source
# File lib/vcr/errors.rb, line 147
def cassettes_description
  if current_cassettes.size > 0
    [cassettes_list << "\n",
     "Under the current configuration VCR can not find a suitable HTTP interaction",
     "to replay and is prevented from recording new requests. There are a few ways",
     "you can deal with this:\n"].join("\n")
  else
    ["There is currently no cassette in use. There are a few ways",
     "you can configure VCR to handle this request:\n"].join("\n")
  end
end
cassettes_list() click to toggle source
# File lib/vcr/errors.rb, line 159
def cassettes_list
  lines = []

  lines << if current_cassettes.size == 1
    "VCR is currently using the following cassette:"
  else
    "VCR are currently using the following cassettes:"
  end

  lines = current_cassettes.inject(lines) do |memo, cassette|
    memo.concat([
       "  - #{cassette.file}",
       "    - :record => #{cassette.record_mode.inspect}",
       "    - :match_requests_on => #{cassette.match_requests_on.inspect}"
    ])
  end

  lines.join("\n")
end
construct_message() click to toggle source
# File lib/vcr/errors.rb, line 81
def construct_message
  ["", "", "=" * 80,
   "An HTTP request has been made that VCR does not know how to handle:",
   "#{request_description}\n",
   cassettes_description,
   formatted_suggestions,
   "=" * 80, "", ""].join("\n")
end
current_cassettes() click to toggle source
# File lib/vcr/errors.rb, line 90
def current_cassettes
  @cassettes ||= begin
    cassettes = VCR.cassettes.to_a.reverse

    begin
      loop do
        break unless VCR.eject_cassette
      end
    rescue EjectLinkedCassetteError
    end

    cassettes
  end
end
current_matchers() click to toggle source
# File lib/vcr/errors.rb, line 129
def current_matchers
  if current_cassettes.size > 0
    current_cassettes.inject([]) do |memo, cassette|
      memo | cassette.match_requests_on
    end
  else
    VCR.configuration.default_cassette_options[:match_requests_on]
  end
end
format_bullet_point(lines, index) click to toggle source
# File lib/vcr/errors.rb, line 194
def format_bullet_point(lines, index)
  lines.first.insert(0, "  * ")
  lines.last << " [#{index + 1}]."
  lines.join("\n    ")
end
format_foot_note(url, index) click to toggle source
# File lib/vcr/errors.rb, line 200
def format_foot_note(url, index)
  "[#{index + 1}] #{url % relish_version_slug}"
end
formatted_headers() click to toggle source
# File lib/vcr/errors.rb, line 139
def formatted_headers
  request.headers.flat_map do |header, values|
    values.map do |val|
      "    #{header}: #{val.inspect}"
    end
  end.join("\n")
end
formatted_suggestions() click to toggle source
# File lib/vcr/errors.rb, line 179
def formatted_suggestions
  formatted_points, formatted_foot_notes = [], []

  suggestions.each_with_index do |suggestion, index|
    bullet_point, foot_note = suggestion.first, suggestion.last
    formatted_points << format_bullet_point(bullet_point, index)
    formatted_foot_notes << format_foot_note(foot_note, index)
  end

  [
    formatted_points.join("\n"),
    formatted_foot_notes.join("\n")
  ].join("\n\n")
end
has_used_interaction_matching?() click to toggle source
# File lib/vcr/errors.rb, line 306
def has_used_interaction_matching?
  current_cassettes.any?{|c| c.http_interactions.has_used_interaction_matching?(request) }
end
match_request_on_body?() click to toggle source
# File lib/vcr/errors.rb, line 125
def match_request_on_body?
  current_matchers.include?(:body)
end
match_request_on_headers?() click to toggle source
# File lib/vcr/errors.rb, line 121
def match_request_on_headers?
  current_matchers.include?(:headers)
end
match_requests_on_suggestion() click to toggle source
# File lib/vcr/errors.rb, line 310
def match_requests_on_suggestion
  num_remaining_interactions = current_cassettes.inject(0) { |sum, c|
    sum + c.http_interactions.remaining_unused_interaction_count
  }

  return [] if num_remaining_interactions.zero?

  interaction_description = if num_remaining_interactions == 1
    "1 HTTP interaction that has"
  else
    "#{num_remaining_interactions} HTTP interactions that have"
  end

  description_lines, link = suggestion_for(:match_requests_on)
  description_lines[0] = description_lines[0] % interaction_description
  [[description_lines, link]]
end
no_cassette_suggestions() click to toggle source
# File lib/vcr/errors.rb, line 288
def no_cassette_suggestions
  [:try_debug_logger, :use_a_cassette, :allow_http_connections_when_no_cassette, :ignore_request].map do |key|
    suggestion_for(key)
  end
end
record_mode_suggestion() click to toggle source
# File lib/vcr/errors.rb, line 294
def record_mode_suggestion
  record_modes = current_cassettes.map(&:record_mode)

  if record_modes.all?{|r| r == :none }
    [:deal_with_none]
  elsif record_modes.all?{|r| r == :once }
    [:delete_cassette_for_once]
  else
    []
  end
end
relish_version_slug() click to toggle source
# File lib/vcr/errors.rb, line 77
def relish_version_slug
  @relish_version_slug ||= VCR.version.gsub(/\W/, '-')
end
request_description() click to toggle source
# File lib/vcr/errors.rb, line 105
def request_description
  lines = []

  lines << "  #{request.method.to_s.upcase} #{request.uri}"

  if match_request_on_headers?
    lines << "  Headers:\n#{formatted_headers}"
  end

  if match_request_on_body?
    lines << "  Body: #{request.body}"
  end

  lines.join("\n")
end
suggestion_for(key) click to toggle source
# File lib/vcr/errors.rb, line 270
def suggestion_for(key)
  bullet_point_lines, url = ALL_SUGGESTIONS[key]
  bullet_point_lines = bullet_point_lines.map(&:dup)
  url = url.dup
  [bullet_point_lines, url]
end
suggestions() click to toggle source
# File lib/vcr/errors.rb, line 277
def suggestions
  return no_cassette_suggestions if current_cassettes.size == 0

  [:try_debug_logger, :use_new_episodes, :ignore_request].tap do |suggestions|
    suggestions.push(*record_mode_suggestion)
    suggestions << :allow_playback_repeats if has_used_interaction_matching?
    suggestions.map! { |k| suggestion_for(k) }
    suggestions.push(*match_requests_on_suggestion)
  end
end