Class: Flail::Exception

Inherits:
Object
  • Object
show all
Defined in:
lib/flail/exception.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(env, exception, local = false) ⇒ Exception

Returns a new instance of Exception.



15
16
17
18
# File 'lib/flail/exception.rb', line 15

def initialize(env, exception, local = false)
  @exception = exception
  @env = env
end

Class Method Details

.notify(exception, request_data = {}) ⇒ Object



6
7
8
9
10
11
12
13
# File 'lib/flail/exception.rb', line 6

def self.notify(exception, request_data = {})
  exception.set_backtrace(Kernel.caller) if exception.backtrace.nil?
  env = {'flail.request' => {'user_agent' => 'internal'}}

  fe = Flail::Exception.new(env, exception)
  fe.request_data = fe.request_data.merge(request_data)
  fe.handle!
end

Instance Method Details

#clean_rack_env(data) ⇒ Object



83
84
85
86
87
# File 'lib/flail/exception.rb', line 83

def clean_rack_env(data)
  data.delete("rack.request.form_vars")
  data.delete("rack.input")
  data
end

#clean_unserializable_data(data, stack = []) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/flail/exception.rb', line 54

def clean_unserializable_data(data, stack = [])
  return "[possible infinite recursion halted]" if stack.any? {|item| item == data.object_id}

  if data.respond_to?(:to_hash)
    data.to_hash.inject({}) do |result, (key, value)|
      result.merge(key => clean_unserializable_data(value, stack + [data.object_id]))
    end
  elsif data.respond_to?(:to_ary)
    data.to_ary.collect do |value|
      clean_unserializable_data(value, stack + [data.object_id])
    end
  else
    input = if ''.respond_to?(:encode)
              data.to_s.encode(Encoding::UTF_8, :undef => :replace)
            else
              require 'iconv'
              ic = Iconv.new("UTF-8//IGNORE", "UTF-8")
              ic.iconv(data.to_s + ' ')[0..-2]
            end
    begin
      input.to_json
    rescue Exception => e
      input = "redundant utf-8 sequence"
    end

    input
  end
end

#extractObject



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/flail/exception.rb', line 97

def extract
  @extract ||= begin
                 info = {}

                 # rack env
                 info[:rack]        = clean_unserializable_data(clean_rack_env(@env.dup))

                 info[:class_name]  = @exception.class.name             # @exception class
                 info[:message]     = @exception.to_s                   # error message
                 info[:target_url]  = request_data[:target_url]         # url of request
                 info[:referer_url] = request_data[:referer_url]        # referer
                 info[:user_agent]  = request_data[:user_agent]         # user agent
                 info[:user]        = request_data[:user]               # current user

                 # backtrace of error
                 info[:trace]       = Flail::Backtrace.parse(@exception.backtrace, :filters => Flail::Backtrace::DEFAULT_FILTERS).to_ary

                 # request parameters
                 info[:parameters]  = clean_unserializable_data(request_data[:parameters])

                 # session
                 info[:session_data]= clean_unserializable_data(request_data[:session_data])

                 # special variables
                 info[:environment] = Flail.configuration.env
                 info[:hostname]    = Flail.configuration.hostname
                 info[:tag]         = Flail.configuration.tag

                 info
               end
end

#handle!Object

Handling the exception



93
94
95
# File 'lib/flail/exception.rb', line 93

def handle!
  Flail.swing(self.extract.to_json) unless self.ignore?
end

#ignore?Boolean

Returns:

  • (Boolean)


129
130
131
132
133
134
135
136
137
138
# File 'lib/flail/exception.rb', line 129

def ignore?
  # Ignore requests with user agent string matching
  # this regxp as they are surely made by bots
  user_agents = request.respond_to?(:user_agent) ? request.user_agent : @env['HTTP_USER_AGENT'].to_s
  if user_agents =~ /\b(Baidu|Gigabot|Googlebot|libwww-perl|lwp-trivial|msnbot|SiteUptime|Slurp|WordPress|ZIBB|ZyBorg|Yandex|Jyxobot|Huaweisymantecspider|ApptusBot)\b/i
    return true
  end

  false
end

#requestObject

Helpers



23
24
25
26
27
28
29
30
31
# File 'lib/flail/exception.rb', line 23

def request
  @request ||= if @env['flail.request']
                 @env['flail.request']
               elsif defined?(ActionDispath::Request)
                 ActionDispatch::Request.new(@env)
               else
                 nil
               end
end

#request_dataObject



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/flail/exception.rb', line 33

def request_data
  @request_data ||= if @env['flail.request.data']
                      @env['flail.request.data']
                    elsif @env['action_dispatch.request.parameters']
                      # Hopefully temporary hack to get at least the params out of Rails 3 applications
                      {
                        :parameters => @env['action_dispatch.request.parameters'],
                        :user => {}
                      }
                    else
                      {
                        :parameters => {},
                        :user => {},
                      }
                    end
end

#request_data=(value) ⇒ Object



50
51
52
# File 'lib/flail/exception.rb', line 50

def request_data=(value)
  @request_data = value
end