Class: RescueRegistry::ExceptionHandler

Inherits:
Object
  • Object
show all
Defined in:
lib/rescue_registry/exception_handler.rb

Direct Known Subclasses

RailsExceptionHandler

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(exception, **options) ⇒ ExceptionHandler

Use a glob for options so that unknown values won’t throw errors. Also, this list could get long…



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/rescue_registry/exception_handler.rb', line 10

def initialize(exception, **options)
  @exception = exception

  @status = options[:status]

  @title = options[:title]

  @detail = options[:detail]
  if options[:message] && @detail.nil?
    # Deprecated, from GraphitiErrors
    @detail = (options[:message] == true) ? :exception : options[:message]
  end

  @meta = options[:meta]
  @code = options[:code]

  # TODO: Warn about unrecognized options
end

Instance Attribute Details

#exceptionObject (readonly)

Returns the value of attribute exception.



29
30
31
# File 'lib/rescue_registry/exception_handler.rb', line 29

def exception
  @exception
end

#statusObject (readonly) Also known as: status_code

Returns the value of attribute status.



29
30
31
# File 'lib/rescue_registry/exception_handler.rb', line 29

def status
  @status
end

Class Method Details

.default_statusObject



5
6
7
# File 'lib/rescue_registry/exception_handler.rb', line 5

def self.default_status
  500
end

Instance Method Details

#build_payload(show_details: false, traces: nil) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/rescue_registry/exception_handler.rb', line 66

def build_payload(show_details: false, traces: nil)
  payload_meta = meta

  if show_details
    payload_meta = payload_meta.merge(
      __details__: {
        exception: exception.inspect,
        traces: traces || [exception.backtrace]
      }
    )
  end

  error_payload = {
    code: error_code,
    status: status_code.to_s,
    title: title
  }

  if (d = detail)
    error_payload[:detail] = d
  end

  error_payload[:meta] = payload_meta if payload_meta.any?

  {
    errors: [error_payload]
  }
end

#detailObject



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/rescue_registry/exception_handler.rb', line 40

def detail
  detail =
    case @detail
    when :exception
      exception.message
    when Proc
      @detail.call(exception)
    else
      if @detail.respond_to?(:to_s)
        val = @detail.to_s
        # Don't return empty string
        val.empty? ? nil : val
      end
    end

  detail || default_detail_for_status
end

#error_codeObject



32
33
34
# File 'lib/rescue_registry/exception_handler.rb', line 32

def error_code
  @code.presence || error_code_from_status
end

#formatted_response(content_type, fallback: :none, **options) ⇒ Object

‘content_type` should be an object with:

* `to_sym` returning sane name for the content_type (e.g. :jsonapi, :json, :xml, :html)
* `to_s` returning the content_type string (e.g. "application/vnd.api+json", "application/json", "text/xml", "text/html")


98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/rescue_registry/exception_handler.rb', line 98

def formatted_response(content_type, fallback: :none, **options)
  body = build_payload(**options)

  # TODO: Maybe make a helper to register these types?
  to_format = content_type.to_sym == :jsonapi ? "to_json" : "to_#{content_type.to_sym}"

  if content_type && body.respond_to?(to_format)
    formatted_body = body.public_send(to_format)
    format = content_type
  else
    case fallback.to_sym
    when :json
      formatted_body = body.to_json
      # FIXME: This won't work without Rails
      format = fallback
    when :none
      return nil
    else
      raise ArgumentError, "unknown fallback=#{fallback}"
    end
  end

  [status_code, formatted_body, format]
end

#metaObject



58
59
60
61
62
63
64
# File 'lib/rescue_registry/exception_handler.rb', line 58

def meta
  if @meta.is_a?(Proc)
    @meta.call(exception)
  else
    { }
  end
end

#titleObject



36
37
38
# File 'lib/rescue_registry/exception_handler.rb', line 36

def title
  @title || title_from_status
end