Class: Immunio::ExceptionHandler

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

Overview

Rack middleware trigger proper hook whenever an exception is raised in the app.

Instance Method Summary collapse

Constructor Details

#initialize(app) ⇒ ExceptionHandler

Returns a new instance of ExceptionHandler.



7
8
9
# File 'lib/immunio/plugins/exception_handler.rb', line 7

def initialize(app)
  @app = app
end

Instance Method Details

#call(env) ⇒ Object



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/immunio/plugins/exception_handler.rb', line 11

def call(env)
  @app.call(env)
rescue RequestBlocked
  Request.time "plugin", "#{Module.nesting[0]}::#{__method__}[RequestBlocked]" do
    # Avoid bubbling exception to logging middlewares.
    Immunio.blocked_app.call(env)
  end
rescue OverrideResponse => override
  status, headers, body = Immunio.override_response.call(env, override)

  Immunio.run_hook "http_tracker", "http_response_start",
    status: status, headers: headers
  [status, headers, body]
rescue StandardError => e
  Request.time "plugin", "#{Module.nesting[0]}::#{__method__}[#{e.class}]" do
    # Check for template, DB errors and such generated by the agent.
    original_exception = unwrap_exception(e)
    if RequestBlocked === original_exception || original_exception.message =~ /^Immunio::RequestBlocked:/
      return Immunio.blocked_app.call(env)
    end
    if OverrideResponse === original_exception  # We can't do anything with just the message:
      status, headers, body = Immunio.override_response.call(env, original_exception)

      Immunio.run_hook "http_tracker", "http_response_start",
        status: status, headers: headers
      return [status, headers, body]
    end

    # A real app exception, not generated by the agent.
    Immunio.run_hook! "exception_handler", "exception", exception: "#{e.class.name}: #{e}"

    # Re-raise
    raise
  end
end

#unwrap_exception(e) ⇒ Object

Unwrap the innermost original exception.



48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/immunio/plugins/exception_handler.rb', line 48

def unwrap_exception(e)
  if Rails::VERSION::MAJOR > 4
    while e.respond_to?(:cause) && e.cause.is_a?(Exception)
      e = e.cause
    end
  else
    while e.respond_to?(:original_exception) && e.original_exception.is_a?(Exception)
      e = e.original_exception
    end
  end
  e
end