rescue_registry 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 528eb94a1296262f6cb1d20d7b8209072147c72e392dabb468fdbb0d2e4d9f43
4
- data.tar.gz: 296ea4a7f1a08fa3fbd981c1ec08e35e528befc17b4167a51b5cdcd480783229
3
+ metadata.gz: abb4709b529437899b1f600805b3218d82581ba88c03642561d015385776dee3
4
+ data.tar.gz: 1f3efb50ac2375c0b204bb8af849615922f48d74c2eb06179a72bef6ce101754
5
5
  SHA512:
6
- metadata.gz: 076d737ba7c477015a3b984e34d2c3782b56688d039db35b27d9cf8d89b682755e1a01c0cae34996ab63ed1fdf2a6e20c8b945d8f1b84c1a5a196f002b060b6c
7
- data.tar.gz: 46c7d35672ecb8d4f04b5d2cad6f4d9844ef3d6d5600c6ba2eaa090a638c2bce77f180163523c5bda7ca646db6355f172ce70da996bc9fbc5b9f6d9b4bcf7191
6
+ metadata.gz: b3025ac89186c93d3d16eea9f1aa4039955d4527eefbeccc939f7501753ad3f9ea306ebc3e705009ee06e9bfd928db5521643d159646e54c271642a2c9e358f0
7
+ data.tar.gz: f3df89c3ea0204a2388b6ccd40deb6d4061586207dc8dca97b2475b07027e28a1db19574741487fb439e7c755bf5d79c9c3f687d4ac20663b5bf2d32b5995b41
@@ -7,4 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ---
9
9
 
10
- No releases means no changes...
10
+ ## [0.2.0] - 2019-05-21
11
+ ### Added
12
+ - Support for non-Rails applications.
13
+ ### Changed
14
+ - Passthrough statuses are currently only support for Rails applications.
15
+ - Added a new Rails middleware for handling the current context.
16
+ ### Fixed
17
+ - Registry is now properly inherited so that new registrations in subclasses do not affect the parent.
18
+ - Default exception handler now works property in the root context.
19
+
20
+ ## [0.1.0] - 2019-05-15
21
+ ### Added
22
+ - Everything, it's the first release!
@@ -3,11 +3,15 @@
3
3
  require 'active_support'
4
4
 
5
5
  module RescueRegistry
6
+ autoload :ActionDispatch, "rescue_registry/action_dispatch"
7
+ autoload :Context, "rescue_registry/context"
6
8
  autoload :Controller, "rescue_registry/controller"
7
9
  autoload :ExceptionsApp, "rescue_registry/exceptions_app"
8
10
  autoload :ExceptionHandler, "rescue_registry/exception_handler"
9
11
  autoload :RailsExceptionHandler, "rescue_registry/exception_handler"
10
12
  autoload :Registry, "rescue_registry/registry"
13
+ autoload :ResetContext, "rescue_registry/reset_context"
14
+ autoload :ShowExceptions, "rescue_registry/show_exceptions"
11
15
 
12
16
  class HandlerNotFound < StandardError; end
13
17
 
@@ -43,9 +47,16 @@ module RescueRegistry
43
47
  end
44
48
  end
45
49
 
50
+ ActiveSupport.on_load(:before_initialize) do
51
+ ActionDispatch::ExceptionWrapper.singleton_class.prepend RescueRegistry::ActionDispatch::ExceptionWrapper
52
+ ActionDispatch::DebugExceptions.prepend RescueRegistry::ActionDispatch::DebugExceptions
53
+ ActionDispatch::ShowExceptions.prepend RescueRegistry::ActionDispatch::ShowExceptions
54
+ end
55
+
46
56
  ActiveSupport.on_load(:action_controller) do
47
57
  include RescueRegistry::Controller
48
58
  end
49
59
 
50
- require 'rescue_registry/action_dispatch'
51
- require 'rescue_registry/railtie'
60
+ if defined?(Rails)
61
+ require 'rescue_registry/railtie'
62
+ end
@@ -1,71 +1,7 @@
1
- require 'action_dispatch'
2
-
3
- ActionDispatch::ExceptionWrapper.class_eval do
4
- class << self
5
- alias_method :status_code_for_exception_without_rescue_registry, :status_code_for_exception
6
- def status_code_for_exception(class_name)
7
- RescueRegistry.status_code_for_exception(class_name) ||
8
- status_code_for_exception_without_rescue_registry(class_name)
9
- end
10
- end
11
- end
12
-
13
- # Since this is for debugging only it's less critical to make changes here. The main area that matters is
14
- # returning the correct status code. Since all this code relies upon the ExceptionWrapper which we've monkeypatched,
15
- # it should work correctly without changes. However, we can provide more details in some areas so we hook in for that.
16
- ActionDispatch::DebugExceptions.class_eval do
17
- private
18
-
19
- # `#log_error`
20
- # TODO: We may be able to add more information, though the details remain to be determined
21
-
22
- # `#render_for_browser_request`
23
- # TODO: We may be able to add more information, though the details remain to be determined
24
-
25
- # This would work without changes, but the formatting would be incorrect. Since it's for debugging only,
26
- # we could choose to ignore it, but the detailed information would definitely be useful.
27
- alias_method :render_for_api_request_without_rescue_registry, :render_for_api_request
28
- def render_for_api_request(content_type, wrapper)
29
- response = nil
30
-
31
- if RescueRegistry.handles_exception?(wrapper.exception)
32
- # Ideally `render_for_api_request` would be split up so we could avoid some duplication in RescueRegistry
33
- begin
34
- response = RescueRegistry.response_for_debugging(content_type, wrapper.exception, traces: wrapper.traces)
35
- rescue Exception => e
36
- # Replace the original exception (still available via `cause`) and let it get handled with default handlers
37
- wrapper = ActionDispatch::ExceptionWrapper.new(wrapper.backtrace_cleaner, e)
38
- end
39
- end
40
-
41
- if response
42
- render(*response)
43
- else
44
- # One of the following is true:
45
- # - No handler for the exception
46
- # - No response for content_type
47
- # - An exception while generating the response
48
- # In any case, we go with the default here.
49
- render_for_api_request_without_rescue_registry(content_type, wrapper)
50
- end
51
- end
52
- end
53
-
54
- ActionDispatch::ShowExceptions.class_eval do
55
- # @private
56
- alias_method :initialize_without_rescue_registry, :initialize
57
-
58
- # @private
59
- def initialize(*args)
60
- initialize_without_rescue_registry(*args)
61
- @exceptions_app = RescueRegistry::ExceptionsApp.new(@exceptions_app)
62
- end
63
-
64
- alias_method :call_without_rescue_registry, :call
65
- def call(*args)
66
- warn "Didn't expect RescueRegistry context to be set in middleware" if RescueRegistry.context
67
- call_without_rescue_registry(*args)
68
- ensure
69
- RescueRegistry.context = nil
1
+ module RescueRegistry
2
+ module ActionDispatch
3
+ autoload :DebugExceptions, "rescue_registry/action_dispatch/debug_exceptions"
4
+ autoload :ExceptionWrapper, "rescue_registry/action_dispatch/exception_wrapper"
5
+ autoload :ShowExceptions, "rescue_registry/action_dispatch/show_exceptions"
70
6
  end
71
7
  end
@@ -0,0 +1,43 @@
1
+ module RescueRegistry
2
+ module ActionDispatch
3
+ # Since this is for debugging only it's less critical to make changes here. The main area that matters is
4
+ # returning the correct status code. Since all this code relies upon the ExceptionWrapper which we've monkeypatched,
5
+ # it should work correctly without changes. However, we can provide more details in some areas so we hook in for that.
6
+ module DebugExceptions
7
+ private
8
+
9
+ # `#log_error`
10
+ # TODO: We may be able to add more information, though the details remain to be determined
11
+
12
+ # `#render_for_browser_request`
13
+ # TODO: We may be able to add more information, though the details remain to be determined
14
+
15
+ # This would work without changes, but the formatting would be incorrect. Since it's for debugging only,
16
+ # we could choose to ignore it, but the detailed information would definitely be useful.
17
+ def render_for_api_request(content_type, wrapper)
18
+ response = nil
19
+
20
+ if RescueRegistry.handles_exception?(wrapper.exception)
21
+ # Ideally `render_for_api_request` would be split up so we could avoid some duplication in RescueRegistry
22
+ begin
23
+ response = RescueRegistry.response_for_debugging(content_type, wrapper.exception, traces: wrapper.traces)
24
+ rescue Exception => e
25
+ # Replace the original exception (still available via `cause`) and let it get handled with default handlers
26
+ wrapper = ActionDispatch::ExceptionWrapper.new(wrapper.backtrace_cleaner, e)
27
+ end
28
+ end
29
+
30
+ if response
31
+ render(*response)
32
+ else
33
+ # One of the following is true:
34
+ # - No handler for the exception
35
+ # - No response for content_type
36
+ # - An exception while generating the response
37
+ # In any case, we go with the default here.
38
+ super(content_type, wrapper)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,9 @@
1
+ module RescueRegistry
2
+ module ActionDispatch
3
+ module ExceptionWrapper
4
+ def status_code_for_exception(class_name)
5
+ RescueRegistry.status_code_for_exception(class_name, passthrough: false) || super
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,17 @@
1
+ module RescueRegistry
2
+ module ActionDispatch
3
+ module ShowExceptions
4
+ def initialize(*args)
5
+ super
6
+ @exceptions_app = RescueRegistry::ExceptionsApp.new(@exceptions_app)
7
+ end
8
+
9
+ def call(*args)
10
+ warn "Didn't expect RescueRegistry context to be set in middleware" if RescueRegistry.context
11
+ super
12
+ ensure
13
+ RescueRegistry.context = nil
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,37 @@
1
+ module RescueRegistry
2
+ module Context
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ if respond_to?(:class_attribute)
7
+ # Prevents subclasses from sharing, but only available to classes
8
+ class_attribute :rescue_registry
9
+ else
10
+ # Allows this module to be included in a module
11
+ mattr_accessor :rescue_registry
12
+ end
13
+
14
+ self.rescue_registry = Registry.new(self)
15
+
16
+ class << self
17
+ delegate :register_exception, to: :rescue_registry
18
+ end
19
+ end
20
+
21
+ def rescue_registry
22
+ self.class.rescue_registry
23
+ end
24
+
25
+ class_methods do
26
+ def inherited(subklass)
27
+ super
28
+ subklass.rescue_registry = rescue_registry.dup
29
+ subklass.rescue_registry.owner = subklass
30
+ end
31
+
32
+ def default_exception_handler
33
+ ExceptionHandler
34
+ end
35
+ end
36
+ end
37
+ end
@@ -3,16 +3,7 @@ module RescueRegistry
3
3
  extend ActiveSupport::Concern
4
4
 
5
5
  included do
6
- cattr_accessor :rescue_registry
7
- self.rescue_registry = Registry.new(self)
8
-
9
- class << self
10
- delegate :register_exception, to: :rescue_registry
11
- end
12
- end
13
-
14
- def rescue_registry
15
- self.class.rescue_registry
6
+ include Context
16
7
  end
17
8
 
18
9
  def process_action(*args)
@@ -32,17 +23,5 @@ module RescueRegistry
32
23
 
33
24
  super
34
25
  end
35
-
36
- class_methods do
37
- def inherited(subklass)
38
- super
39
- subklass.rescue_registry = rescue_registry.dup
40
- subklass.rescue_registry.owner = subklass
41
- end
42
-
43
- def default_exception_handler
44
- ExceptionHandler
45
- end
46
- end
47
26
  end
48
27
  end
@@ -1,3 +1,5 @@
1
+ require 'json'
2
+
1
3
  module RescueRegistry
2
4
  class ExceptionHandler
3
5
  def self.default_status
@@ -8,11 +10,7 @@ module RescueRegistry
8
10
  def initialize(exception, **options)
9
11
  @exception = exception
10
12
 
11
- status = options[:status]
12
- if status == :passthrough
13
- status = ActionDispatch::ExceptionWrapper.status_code_for_exception_without_rescue_registry(exception.class.name)
14
- end
15
- @status = status
13
+ @status = options[:status]
16
14
 
17
15
  @title = options[:title]
18
16
 
@@ -46,10 +44,14 @@ module RescueRegistry
46
44
  when Proc
47
45
  @detail.call(exception)
48
46
  else
49
- @detail.try(:to_s)
47
+ if @detail.respond_to?(:to_s)
48
+ val = @detail.to_s
49
+ # Don't return empty string
50
+ val.empty? ? nil : val
51
+ end
50
52
  end
51
53
 
52
- detail.presence || default_detail_for_status
54
+ detail || default_detail_for_status
53
55
  end
54
56
 
55
57
  def meta
@@ -83,20 +85,25 @@ module RescueRegistry
83
85
  }
84
86
  end
85
87
 
86
- def formatted_response(content_type, fallback: :json, **options)
88
+ # `content_type` should be an object with:
89
+ # * `to_sym` returning sane name for the content_type (e.g. :jsonapi, :json, :xml, :html)
90
+ # * `to_s` returning the content_type string (e.g. "application/vnd.api+json", "application/json", "text/xml", "text/html")
91
+ def formatted_response(content_type, fallback: :none, **options)
87
92
  body = build_payload(**options)
88
93
 
89
94
  # TODO: Maybe make a helper to register these types?
90
- to_format = content_type == :jsonapi ? "to_json" : "to_#{content_type.to_sym}"
95
+ to_format = content_type.to_sym == :jsonapi ? "to_json" : "to_#{content_type.to_sym}"
91
96
 
92
97
  if content_type && body.respond_to?(to_format)
93
98
  formatted_body = body.public_send(to_format)
94
99
  format = content_type
95
100
  else
96
- if fallback == :json
101
+ case fallback.to_sym
102
+ when :json
97
103
  formatted_body = body.to_json
98
- format = Mime[:json]
99
- elsif fallback == :none
104
+ # FIXME: This won't work without Rails
105
+ format = fallback
106
+ when :none
100
107
  return nil
101
108
  else
102
109
  raise ArgumentError, "unknown fallback=#{fallback}"
@@ -5,7 +5,7 @@ module RescueRegistry
5
5
  end
6
6
 
7
7
  def call(env)
8
- request = ActionDispatch::Request.new(env)
8
+ request = ::ActionDispatch::Request.new(env)
9
9
  exception = request.get_header "action_dispatch.exception"
10
10
 
11
11
  if RescueRegistry.handles_exception?(exception)
@@ -15,20 +15,23 @@ module RescueRegistry
15
15
  content_type = Mime[:text]
16
16
  end
17
17
 
18
- if (response = RescueRegistry.response_for_public(content_type, exception))
19
- status, body, format = response
18
+ response = RescueRegistry.response_for_public(content_type, exception)
19
+ end
20
20
 
21
- if request.path_info != "/#{status}"
22
- warn "status mismatch; path_info=#{request.path_info}; status=#{status}"
23
- end
21
+ if response
22
+ status, body, format = response
24
23
 
25
- [status, { "Content-Type" => "#{format}; charset=#{ActionDispatch::Response.default_charset}",
26
- "Content-Length" => body.bytesize.to_s }, [body]]
27
- else
28
- # If we have no response, it means we couldn't render for the content_type, use the default handler instead
29
- @app.call(env)
24
+ if request.path_info != "/#{status}"
25
+ warn "status mismatch; path_info=#{request.path_info}; status=#{status}"
30
26
  end
27
+
28
+ [status, { "Content-Type" => "#{format}; charset=#{::ActionDispatch::Response.default_charset}",
29
+ "Content-Length" => body.bytesize.to_s }, [body]]
31
30
  else
31
+ # If we have no response, it means one of the following:
32
+ # * RescueRegistry doesn't handle this exception
33
+ # * RescueRegistry doesn't have a response to render for this content_type.
34
+ # In either case, we use the default handler instead
32
35
  @app.call(env)
33
36
  end
34
37
  end
@@ -1,8 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'rails/railtie'
4
-
5
3
  module RescueRegistry
6
4
  class Railtie < Rails::Railtie
5
+ initializer "rescue_registry.add_middleware" do |app|
6
+ # We add this middleware to ensure that the RescueRegistry.context is properly handled.
7
+ # The context is set in the controller action and will be available until the Middleware
8
+ # returns. Any middleware that are before this one will not have access to the context.
9
+ app.middleware.insert_before ::ActionDispatch::ShowExceptions, RescueRegistry::ResetContext
10
+ end
7
11
  end
8
12
  end
@@ -3,7 +3,7 @@ module RescueRegistry
3
3
  attr_accessor :owner
4
4
 
5
5
  def initialize(owner)
6
- @owner = self
6
+ @owner = owner
7
7
  @handlers = { }
8
8
  end
9
9
 
@@ -11,16 +11,28 @@ module RescueRegistry
11
11
  @handlers = @handlers.dup
12
12
  end
13
13
 
14
+ def passthrough_allowed?
15
+ defined?(ActionDispatch::ExceptionWrapper)
16
+ end
17
+
18
+ def passthrough_status(exception)
19
+ ::ActionDispatch::ExceptionWrapper.status_code_for_exception(exception.class.name)
20
+ end
21
+
14
22
  # TODO: Support a shorthand for handler
15
23
  def register_exception(exception_class, handler: nil, **options)
16
24
  raise ArgumentError, "#{exception_class} is not an Exception" unless exception_class <= Exception
17
25
 
18
- handler ||= owner.try(:default_exception_handler)
26
+ if owner.respond_to?(:default_exception_handler)
27
+ handler ||= owner.default_exception_handler
28
+ end
19
29
  raise ArgumentError, "handler must be provided" unless handler
20
30
 
21
31
  status = options[:status] ||= handler.default_status
22
32
  raise ArgumentError, "status must be provided" unless status
23
- raise ArgumentError, "invalid status: #{status}" unless status.is_a?(Integer) || status == :passthrough
33
+ unless status.is_a?(Integer) || (passthrough_allowed? && status == :passthrough)
34
+ raise ArgumentError, "invalid status: #{status}"
35
+ end
24
36
 
25
37
  # TODO: Validate options here
26
38
 
@@ -33,20 +45,27 @@ module RescueRegistry
33
45
  raise HandlerNotFound, "no handler found for #{exception.class}" unless handler_info
34
46
 
35
47
  handler_class, handler_options = handler_info
48
+
49
+ if handler_options[:status] == :passthrough
50
+ handler_options = handler_options.merge(status: passthrough_status(exception))
51
+ end
52
+
36
53
  handler_class.new(exception, **handler_options)
37
54
  end
38
55
 
39
56
  def handles_exception?(exception)
40
- handler_info_for_exception(exception).present?
57
+ !handler_info_for_exception(exception).nil?
41
58
  end
42
59
 
43
- def status_code_for_exception(exception)
60
+ def status_code_for_exception(exception, passthrough: true)
44
61
  _, options = handler_info_for_exception(exception)
45
62
  return unless options
46
63
 
47
- # Return no code for passthrough.
48
- # Alternatively we could handle this explicitly in the ExceptionWrapper monkeypatch.
49
- options[:status] == :passthrough ? nil : options[:status]
64
+ if options[:status] == :passthrough
65
+ passthrough ? passthrough_status(exception) : nil
66
+ else
67
+ options[:status]
68
+ end
50
69
  end
51
70
 
52
71
  def build_response(content_type, exception, **options)
@@ -54,12 +73,12 @@ module RescueRegistry
54
73
  handler.formatted_response(content_type, **options)
55
74
  end
56
75
 
57
- def response_for_debugging(content_type, exception, traces: nil)
58
- build_response(content_type, exception, show_details: true, traces: traces)
76
+ def response_for_debugging(content_type, exception, traces: nil, fallback: :none)
77
+ build_response(content_type, exception, show_details: true, traces: traces, fallback: fallback)
59
78
  end
60
79
 
61
- def response_for_public(content_type, exception)
62
- build_response(content_type, exception, fallback: :none)
80
+ def response_for_public(content_type, exception, fallback: :none)
81
+ build_response(content_type, exception, fallback: fallback)
63
82
  end
64
83
 
65
84
  private
@@ -0,0 +1,14 @@
1
+ module RescueRegistry
2
+ class ResetContext
3
+ def initialize(app)
4
+ @app = app
5
+ end
6
+
7
+ def call(*args)
8
+ warn "Didn't expect RescueRegistry context to already be set in middleware" if RescueRegistry.context
9
+ @app.call(*args)
10
+ ensure
11
+ RescueRegistry.context = nil
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This is for use in non-Rails Rack apps. Rails apps will handle exceptions with
4
+ # ActionDispatch::DebugExceptions and ActionDispatch::ShowExceptions
5
+ module RescueRegistry
6
+ class ShowExceptions
7
+ # Unfortunately, Rail's nice mime types are in ActionDispatch which we'd rather not require
8
+ CONTENT_TYPES = {
9
+ jsonapi: "application/vnd.api+json",
10
+ json: "application/json",
11
+ xml: ["application/xml", "text/xml"],
12
+ plain: "text/plain"
13
+ }
14
+
15
+ # Match Rail's Mime::Type API on a basic level
16
+ MimeType = Struct.new(:to_sym, :to_s)
17
+
18
+ def initialize(app, debug: false, content_types: CONTENT_TYPES)
19
+ @app = app
20
+ @content_types = content_types
21
+ @debug = debug
22
+ end
23
+
24
+ def call(env)
25
+ @app.call(env)
26
+ rescue Exception => exception
27
+ handle_exception(env, exception)
28
+ end
29
+
30
+ private
31
+
32
+ def handle_exception(env, exception)
33
+ if RescueRegistry.handles_exception?(exception)
34
+ accept = Rack::Utils.best_q_match(env["HTTP_ACCEPT"], @content_types.values.flatten)
35
+ accept ||= "text/plain"
36
+
37
+ symbol = CONTENT_TYPES.find { |(k,v)| Array(v).include?(accept) }.first
38
+ content_type = MimeType.new(symbol, accept)
39
+
40
+ # We need a fallback to ensure that we actually do render something. Outside of Rails, there's no situation where
41
+ # we would want to pass through on a handled exception.
42
+ fallback = MimeType.new(:json, CONTENT_TYPES[:json])
43
+ if @debug
44
+ response = RescueRegistry.response_for_debugging(content_type, exception, traces: { "Full Trace" => exception.backtrace }, fallback: fallback)
45
+ else
46
+ response = RescueRegistry.response_for_public(content_type, exception, fallback: fallback)
47
+ end
48
+ end
49
+
50
+ if response
51
+ status, body, format = response
52
+ [status, { "Content-Type" => "#{format}", "Content-Length" => body.bytesize.to_s }, [body]]
53
+ else
54
+ # Let next middleware handle
55
+ raise exception
56
+ end
57
+ end
58
+ end
59
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RescueRegistry
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
metadata CHANGED
@@ -1,25 +1,22 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rescue_registry
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Wagenet
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-15 00:00:00.000000000 Z
11
+ date: 2019-05-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rails
14
+ name: activesupport
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '5.0'
20
- - - "<"
21
- - !ruby/object:Gem::Version
22
- version: '7.0'
23
20
  type: :runtime
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
@@ -27,9 +24,6 @@ dependencies:
27
24
  - - ">="
28
25
  - !ruby/object:Gem::Version
29
26
  version: '5.0'
30
- - - "<"
31
- - !ruby/object:Gem::Version
32
- version: '7.0'
33
27
  - !ruby/object:Gem::Dependency
34
28
  name: appraisal
35
29
  requirement: !ruby/object:Gem::Requirement
@@ -72,34 +66,6 @@ dependencies:
72
66
  - - "~>"
73
67
  - !ruby/object:Gem::Version
74
68
  version: '3.3'
75
- - !ruby/object:Gem::Dependency
76
- name: rspec-rails
77
- requirement: !ruby/object:Gem::Requirement
78
- requirements:
79
- - - "~>"
80
- - !ruby/object:Gem::Version
81
- version: '3.8'
82
- type: :development
83
- prerelease: false
84
- version_requirements: !ruby/object:Gem::Requirement
85
- requirements:
86
- - - "~>"
87
- - !ruby/object:Gem::Version
88
- version: '3.8'
89
- - !ruby/object:Gem::Dependency
90
- name: sqlite3
91
- requirement: !ruby/object:Gem::Requirement
92
- requirements:
93
- - - "~>"
94
- - !ruby/object:Gem::Version
95
- version: '1.3'
96
- type: :development
97
- prerelease: false
98
- version_requirements: !ruby/object:Gem::Requirement
99
- requirements:
100
- - - "~>"
101
- - !ruby/object:Gem::Version
102
- version: '1.3'
103
69
  - !ruby/object:Gem::Dependency
104
70
  name: yard
105
71
  requirement: !ruby/object:Gem::Requirement
@@ -127,11 +93,17 @@ files:
127
93
  - Rakefile
128
94
  - lib/rescue_registry.rb
129
95
  - lib/rescue_registry/action_dispatch.rb
96
+ - lib/rescue_registry/action_dispatch/debug_exceptions.rb
97
+ - lib/rescue_registry/action_dispatch/exception_wrapper.rb
98
+ - lib/rescue_registry/action_dispatch/show_exceptions.rb
99
+ - lib/rescue_registry/context.rb
130
100
  - lib/rescue_registry/controller.rb
131
101
  - lib/rescue_registry/exception_handler.rb
132
102
  - lib/rescue_registry/exceptions_app.rb
133
103
  - lib/rescue_registry/railtie.rb
134
104
  - lib/rescue_registry/registry.rb
105
+ - lib/rescue_registry/reset_context.rb
106
+ - lib/rescue_registry/show_exceptions.rb
135
107
  - lib/rescue_registry/version.rb
136
108
  - lib/tasks/rescue_registry_tasks.rake
137
109
  homepage: https://github.com/wagenet/rescue_registry