Module: RocketPants::ErrorHandling

Extended by:
ActiveSupport::Concern
Defined in:
lib/rocket_pants/controller/error_handling.rb

Overview

Makes it easier to both throw named exceptions (corresponding to error states in the response) and to then process the response into something useable in the response.

Defined Under Namespace

Modules: ClassMethods

Instance Method Summary collapse

Instance Method Details

#default_message_for_exception(exception) ⇒ Object



61
62
63
64
65
66
67
# File 'lib/rocket_pants/controller/error_handling.rb', line 61

def default_message_for_exception(exception)
  if !RocketPants.show_exception_message? || exception.message == exception.class.name
    'An unknown error has occurred.'
  else
    exception.message
  end
end

#error!(name, context = {}) ⇒ Object #error!(name, message, context = {}) ⇒ Object

Dynamically looks up and then throws the error given by a symbolic name. Optionally takes a string message argument and a hash of ‘context’.

Overloads:

  • #error!(name, context = {}) ⇒ Object

    Parameters:

    • name (Symbol)

      the name of the exception, looked up using RocketPants::Errors

    • context (Hash{Symbol => Object}) (defaults to: {})

      the options passed to the error message translation.

  • #error!(name, message, context = {}) ⇒ Object

    Parameters:

    • name (Symbol)

      the name of the exception, looked up using RocketPants::Errors

    • message (String)

      an optional message describing the error

    • context (Hash{Symbol => Object}) (defaults to: {})

      the options passed to the error message translation.

Raises:



40
41
42
43
44
45
# File 'lib/rocket_pants/controller/error_handling.rb', line 40

def error!(name, *args)
  context   = args.extract_options!
  klass     = Errors[name] || Error
  exception = klass.new(*args).tap { |e| e.context = context }
  raise exception
end

#lookup_error_context(exception) ⇒ Object

Returns the i18n context for a given exception.

Parameters:

  • exception (StandardError)

    the exception to find the context for

  • the (Hash)

    i18n translation context.



92
93
94
# File 'lib/rocket_pants/controller/error_handling.rb', line 92

def lookup_error_context(exception)
  exception.respond_to?(:context) ? exception.context : {}
end

#lookup_error_extras(exception) ⇒ Object



96
97
98
# File 'lib/rocket_pants/controller/error_handling.rb', line 96

def lookup_error_extras(exception)
  {}
end

#lookup_error_message(exception) ⇒ String

From a given exception, gets the corresponding error message using I18n. It will use context (if defined) on the exception for the I18n context base and will use either the result of Error#error_name (if present) or :system for the name of the error.

Parameters:

  • exception (StandardError)

    the exception to get the message from

Returns:

  • (String)

    the found error message.



53
54
55
56
57
58
59
# File 'lib/rocket_pants/controller/error_handling.rb', line 53

def lookup_error_message(exception)
  # TODO: Add in notification hooks for non-standard exceptions.
  name    = lookup_error_name(exception)
  message = default_message_for_exception exception
  context = lookup_error_context(exception).reverse_merge(:scope => :"rocket_pants.errors", :default => message)
  I18n.t name, context.except(:metadata)
end

#lookup_error_metadata(exception) ⇒ Object

Returns extra error details for a given object, making it useable for hooking in external exceptions.



102
103
104
105
# File 'lib/rocket_pants/controller/error_handling.rb', line 102

def (exception)
  context = lookup_error_context exception
  context.fetch(:metadata, {}).merge lookup_error_extras(exception)
end

#lookup_error_name(exception) ⇒ Symbol

Lookup error name will automatically handle translating errors to a simpler, symbol representation. It’s implemented like this to make it possible to override to a simple format.

Parameters:

  • exception (StandardError)

    the exception to find the name for

Returns:

  • (Symbol)

    the name of the given error



74
75
76
77
78
79
80
# File 'lib/rocket_pants/controller/error_handling.rb', line 74

def lookup_error_name(exception)
  if exception.respond_to?(:error_name)
    exception.error_name
  else
    :system
  end
end

#lookup_error_status(exception) ⇒ Symbol

Returns the error status code for a given exception.

Parameters:

  • exception (StandardError)

    the exception to find the status for

Returns:

  • (Symbol)

    the name of the given error



85
86
87
# File 'lib/rocket_pants/controller/error_handling.rb', line 85

def lookup_error_status(exception)
  exception.respond_to?(:http_status) ? exception.http_status : 500
end

#render_error(exception) ⇒ Object

Renders an exception as JSON using a nicer version of the error name and error message, following the typically error standard as laid out in the JSON api design.

Parameters:

  • exception (StandardError)

    the error to render a response for.



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/rocket_pants/controller/error_handling.rb', line 111

def render_error(exception)
  logger.debug "Exception raised: #{exception.class.name}: #{exception.message}" if logger
  # When a normalised class is present, make sure we
  # convert it to a useable error class.
  normalised_class = exception.class.ancestors.detect do |klass|
    klass < StandardError and error_mapping.has_key?(klass)
  end
  if normalised_class
    mapped = error_mapping[normalised_class]
    if mapped.respond_to?(:call)
      exception = mapped.call(exception)
    else
      exception = mapped.new exception.message
    end
  end
  self.status = lookup_error_status(exception)
  render_json({
    :error             => lookup_error_name(exception).to_s,
    :error_description => lookup_error_message(exception)
  }.merge((exception)))
end