error_report.rb
3.48 KB
1
2
3
4
5
6
7
8
9
10
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
46
47
48
49
50
51
52
53
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
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
128
129
130
131
132
133
134
require 'hoptoad_notifier'
##
# Processes a new error report.
#
# Accepts a hash with the following attributes:
#
# * <tt>:error_class</tt> - the class of error
# * <tt>:message</tt> - the error message
# * <tt>:backtrace</tt> - an array of stack trace lines
#
# * <tt>:request</tt> - a hash of values describing the request
# * <tt>:server_environment</tt> - a hash of values describing the server environment
#
# * <tt>:notifier</tt> - information to identify the source of the error report
#
class ErrorReport
attr_reader :api_key
attr_reader :error_class
attr_reader :framework
attr_reader :message
attr_reader :notice
attr_reader :notifier
attr_reader :problem
attr_reader :request
attr_reader :server_environment
attr_reader :user_attributes
def initialize(xml_or_attributes)
@attributes = xml_or_attributes
@attributes = Hoptoad.parse_xml!(@attributes) if @attributes.is_a? String
@attributes = @attributes.with_indifferent_access
@attributes.each { |k, v| instance_variable_set(:"@#{k}", v) }
end
def rails_env
rails_env = server_environment['environment-name']
rails_env = 'development' if rails_env.blank?
rails_env
end
def app
@app ||= App.where(api_key: api_key).first
end
def backtrace
@normalized_backtrace ||= Backtrace.find_or_create(@backtrace)
end
def generate_notice!
return unless valid?
return @notice if @notice
make_notice
notice.err_id = error.id
notice.save!
cache_attributes_on_problem
email_notification
services_notification
@notice
end
def make_notice
@notice = Notice.new(
app: app,
message: message,
error_class: error_class,
backtrace: backtrace,
request: request,
server_environment: server_environment,
notifier: notifier,
user_attributes: user_attributes,
framework: framework
)
end
# Update problem cache with information about this notice
def cache_attributes_on_problem
@problem = Problem.cache_notice(@error.problem_id, @notice)
end
# Send email notification if needed
def email_notification
return false unless app.emailable?
return false unless app.email_at_notices.include?(@problem.notices_count)
Mailer.err_notification(self).deliver_now
rescue => e
HoptoadNotifier.notify(e)
end
def should_notify?
app.notification_service.notify_at_notices.include?(0) ||
app.notification_service.notify_at_notices.include?(@problem.notices_count)
end
# Launch all notification define on the app associate to this notice
def services_notification
return true unless app.notification_service_configured? && should_notify?
app.notification_service.create_notification(problem)
rescue => e
HoptoadNotifier.notify(e)
end
##
# Error associate to this error_report
#
# Can already exist or not
#
# @return [ Error ]
def error
@error ||= app.find_or_create_err!(
error_class: error_class,
environment: rails_env,
fingerprint: fingerprint
)
end
def valid?
app.present?
end
def should_keep?
app_version = server_environment['app-version'] || ''
current_version = app.current_app_version
return true unless current_version.present?
return false if app_version.length <= 0
Gem::Version.new(app_version) >= Gem::Version.new(current_version)
end
def fingerprint
app.notice_fingerprinter.generate(api_key, notice, backtrace)
end
end