Class: Grape::ErrorFormatter::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/grape/error_formatter/base.rb

Direct Known Subclasses

Json, Txt, Xml

Class Method Summary collapse

Class Method Details

.call(error:, env: nil, include_backtrace: false, include_original_exception: false) ⇒ Object

Custom error formatters override call. The error is a frozen Grape::Exceptions::ErrorResponse carrying status/message/ headers/backtrace/original_exception. env is the Rack env (needed by entity-presenter resolution). include_backtrace and include_original_exception are the request-time toggles set by rescue_from; the base implementation embeds the corresponding fields in the response body when they are true.



14
15
16
17
18
19
20
21
22
# File 'lib/grape/error_formatter/base.rb', line 14

def call(error:, env: nil, include_backtrace: false, include_original_exception: false)
  wrapped_message = wrap_message(present(error.message, env))
  if wrapped_message.is_a?(Hash)
    wrapped_message[:backtrace] = error.backtrace if include_backtrace && error.backtrace.present?
    wrapped_message[:original_exception] = error.original_exception.inspect if include_original_exception && error.original_exception
  end

  format_structured_message(wrapped_message)
end

.format_structured_message(_structured_message) ⇒ Object

Raises:

  • (NotImplementedError)


60
61
62
# File 'lib/grape/error_formatter/base.rb', line 60

def format_structured_message(_structured_message)
  raise NotImplementedError
end

.present(message, env) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/grape/error_formatter/base.rb', line 24

def present(message, env)
  # error! accepts a message hash with an optional :with key specifying the entity presenter.
  # Extract it here so the presenter can be resolved and the key is not serialized in the response.
  # See spec/integration/grape_entity/entity_spec.rb for examples.
  with = nil
  if message.is_a?(Hash) && message.key?(:with)
    message = message.dup
    with = message.delete(:with)
  end

  presenter = with || env[Grape::Env::API_ENDPOINT].entity_class_for_obj(message)

  unless presenter || env[Grape::Env::GRAPE_ROUTING_ARGS].nil?
    # env['api.endpoint'].route does not work when the error occurs within a middleware
    # the Endpoint does not have a valid env at this moment
    http_codes = env[Grape::Env::GRAPE_ROUTING_ARGS][:route_info].http_codes || []
    found_code = http_codes.find do |http_code|
      (http_code[0].to_i == env[Grape::Env::API_ENDPOINT].status) && http_code[2].respond_to?(:represent)
    end if env[Grape::Env::API_ENDPOINT].request

    presenter = found_code[2] if found_code
  end

  return message unless presenter

  embeds = { env: }
  embeds[:version] = env[Grape::Env::API_VERSION] if env.key?(Grape::Env::API_VERSION)
  presenter.represent(message, embeds).serializable_hash
end

.wrap_message(message) ⇒ Object



54
55
56
57
58
# File 'lib/grape/error_formatter/base.rb', line 54

def wrap_message(message)
  return message if message.is_a?(Hash)

  { message: }
end