asana_exception_notifier 0.0.4 → 0.0.5
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 +4 -4
- data/Gemfile.lock +1 -1
- data/lib/asana_exception_notifier.rb +1 -0
- data/lib/asana_exception_notifier/classes/asana.rb +4 -6
- data/lib/asana_exception_notifier/classes/error_page.rb +33 -14
- data/lib/asana_exception_notifier/classes/unsafe_filter.rb +53 -0
- data/lib/asana_exception_notifier/helpers/application_helper.rb +29 -9
- data/lib/asana_exception_notifier/helpers/heredoc_helper.rb +3 -8
- data/lib/asana_exception_notifier/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 520178c0df0b87ab02ee7a9e05b3c37f11570796
|
4
|
+
data.tar.gz: cf6746459b95fd0db6f7e7ba5ad184790c0cebfe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8323b25c7d23852e0be40cd00ce98c421544b66f28b5190a44fbafce960cbbbc850e147b28f4f272539361070cd6a410ac6faab265035acace0214a149854506
|
7
|
+
data.tar.gz: 2c94dfe47678d0942c5a3035babcfbb87d46d20084d6ee6e5e99c023ac87a7c2fa994a1991136e2e4a9394703d7947aec77dbdbb6d28023c14155c978b7b9cef
|
data/Gemfile.lock
CHANGED
@@ -13,11 +13,9 @@ module ExceptionNotifier
|
|
13
13
|
attr_reader :initial_options, :default_options
|
14
14
|
|
15
15
|
def initialize(options)
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
parse_options(@initial_options)
|
20
|
-
end
|
16
|
+
super
|
17
|
+
@initial_options = options.symbolize_keys.reject { |_key, value| value.blank? }
|
18
|
+
parse_options(@initial_options)
|
21
19
|
end
|
22
20
|
|
23
21
|
def call(exception, options = {})
|
@@ -98,7 +96,7 @@ module ExceptionNotifier
|
|
98
96
|
end
|
99
97
|
|
100
98
|
def upload_log_file_to_task(error_page, task_data)
|
101
|
-
archives = error_page.
|
99
|
+
archives = error_page.fetch_all_archives
|
102
100
|
archives.each do |zip|
|
103
101
|
upload_archive(zip, task_data)
|
104
102
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative '../helpers/application_helper'
|
2
|
+
require_relative './unsafe_filter'
|
2
3
|
module AsanaExceptionNotifier
|
3
4
|
# class used for rendering the template for exception
|
4
5
|
class ErrorPage
|
@@ -41,11 +42,12 @@ module AsanaExceptionNotifier
|
|
41
42
|
server: Socket.gethostname,
|
42
43
|
exception: @exception,
|
43
44
|
request: @request,
|
44
|
-
environment:
|
45
|
+
environment: @request.respond_to?(:filtered_env) ? @request.filtered_env : @env,
|
45
46
|
rails_root: defined?(Rails) ? Rails.root : nil,
|
46
47
|
process: $PROCESS_ID,
|
47
48
|
data: (@env.blank? ? {} : @env.fetch(:'exception_notifier.exception_data', {})).merge(@options[:data] || {}),
|
48
49
|
exception_data: exception_data,
|
50
|
+
exception_service_data: exception_service,
|
49
51
|
request_data: setup_env_params,
|
50
52
|
uname: Sys::Uname.uname,
|
51
53
|
timestamp: @timestamp,
|
@@ -57,24 +59,37 @@ module AsanaExceptionNotifier
|
|
57
59
|
{
|
58
60
|
error_class: @exception.class.to_s,
|
59
61
|
message: @exception.respond_to?(:message) ? @exception.message : exception.inspect,
|
60
|
-
backtrace: @exception.respond_to?(:backtrace) ? @exception.backtrace :
|
61
|
-
cause: @exception.respond_to?(:cause) ? @exception.cause :
|
62
|
+
backtrace: @exception.respond_to?(:backtrace) ? (@exception.backtrace || []).join("\n") : nil,
|
63
|
+
cause: @exception.respond_to?(:cause) ? @exception.cause : nil
|
64
|
+
}
|
65
|
+
end
|
66
|
+
|
67
|
+
def exception_service
|
68
|
+
{
|
69
|
+
service_class: @exception.respond_to?(:service_class) ? @exception.service_class : nil,
|
70
|
+
arguments: @exception.respond_to?(:service_arguments) ? filter_params(@exception.service_arguments).inspect.gsub(',', ",\n") : nil,
|
71
|
+
service_method: @exception.respond_to?(:service_method) ? @exception.service_method : nil,
|
72
|
+
trace: @exception.respond_to?(:service_backtrace) ? @exception.service_backtrace : nil
|
62
73
|
}
|
63
74
|
end
|
64
75
|
|
65
76
|
def setup_env_params
|
66
77
|
{
|
67
|
-
url:
|
78
|
+
url: @request.respond_to?(:original_url) ? @request.original_url : @request.path_info,
|
68
79
|
referrer: @request.referer,
|
69
80
|
http_method: action_dispatch? ? @request.method : @request.request_method,
|
70
|
-
ip_address:
|
71
|
-
parameters:
|
81
|
+
ip_address: @request.respond_to?(:remote_ip) ? @request.remote_ip : @request.ip,
|
82
|
+
parameters: @request.respond_to?(:filtered_parameters) ? filter_params(@request.filtered_parameters) : filter_params(request_params),
|
72
83
|
session: @request.session,
|
73
84
|
cookies: @request.cookies,
|
74
85
|
user_agent: @request.user_agent
|
75
86
|
}
|
76
87
|
end
|
77
88
|
|
89
|
+
def filter_params(params)
|
90
|
+
AsanaExceptionNotifier::UnsafeFilter.new(params, @options.fetch(:unsafe_options, []))
|
91
|
+
end
|
92
|
+
|
78
93
|
def request_params
|
79
94
|
@request.params
|
80
95
|
rescue
|
@@ -100,7 +115,7 @@ module AsanaExceptionNotifier
|
|
100
115
|
def add_to_links(links, prefix, options = {})
|
101
116
|
expected_value = parse_fieldset_value(options)
|
102
117
|
return unless expected_value.present?
|
103
|
-
prefix_name = set_fieldset_key(links, prefix
|
118
|
+
prefix_name = set_fieldset_key(links, prefix, 'basic_info')
|
104
119
|
links[prefix_name][options[:key]] = expected_value
|
105
120
|
end
|
106
121
|
|
@@ -123,14 +138,18 @@ module AsanaExceptionNotifier
|
|
123
138
|
tempfile_details(tempfile).slice(:filename, :path).values
|
124
139
|
end
|
125
140
|
|
141
|
+
def fetch_all_archives
|
142
|
+
fetch_archives
|
143
|
+
rescue
|
144
|
+
[]
|
145
|
+
end
|
146
|
+
|
126
147
|
def fetch_archives(output = render_template)
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
split_archive(archive, "part_#{filename}", 1024 * 1024 * 100)
|
133
|
-
end
|
148
|
+
return [] if output.blank?
|
149
|
+
filename, path = create_tempfile(output)
|
150
|
+
archive = compress_files(File.dirname(path), filename, [expanded_path(path)])
|
151
|
+
remove_tempfile(path)
|
152
|
+
split_archive(archive, "part_#{filename}", 1024 * 1024 * 100)
|
134
153
|
end
|
135
154
|
|
136
155
|
def remove_tempfile(path)
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require_relative '../helpers/application_helper'
|
2
|
+
module AsanaExceptionNotifier
|
3
|
+
# class used to filter unsafe params
|
4
|
+
class UnsafeFilter
|
5
|
+
include AsanaExceptionNotifier::ApplicationHelper
|
6
|
+
|
7
|
+
UNSAFE_OPTIONS = %w(
|
8
|
+
password password_confirmation new_password new_password_confirmation
|
9
|
+
old_password email_address email authenticity_token utf8
|
10
|
+
).freeze
|
11
|
+
|
12
|
+
attr_reader :arguments, :unsafe_options
|
13
|
+
|
14
|
+
def initialize(arguments, unsafe_options = [])
|
15
|
+
@unsafe_options = unsafe_options.present? && unsafe_options.is_a?(Array) ? unsafe_options.map(&:to_s) : []
|
16
|
+
@arguments = arguments.present? ? arguments : {}
|
17
|
+
remove_unsafe(@arguments)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def remove_unsafe(args)
|
23
|
+
return args if args.blank?
|
24
|
+
args.delete(:attributes!)
|
25
|
+
remove_blank(args)
|
26
|
+
remove_unsafe_from_object(args)
|
27
|
+
args
|
28
|
+
end
|
29
|
+
|
30
|
+
def remove_unsafe_from_object(args)
|
31
|
+
if args.is_a?(Hash)
|
32
|
+
args.each_pair do |key, value|
|
33
|
+
verify_unsafe_pair(key, value)
|
34
|
+
end
|
35
|
+
else
|
36
|
+
remove_unsafe(value: args)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def unsafe?(key)
|
41
|
+
@unsafe_options.include?(key) || AsanaExceptionNotifier::UnsafeFilter::UNSAFE_OPTIONS.include?(key)
|
42
|
+
end
|
43
|
+
|
44
|
+
def verify_unsafe_pair(key, value)
|
45
|
+
case value
|
46
|
+
when Hash
|
47
|
+
remove_unsafe(value)
|
48
|
+
else
|
49
|
+
args.delete(key) if unsafe?(key.to_s)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -23,7 +23,8 @@ module AsanaExceptionNotifier
|
|
23
23
|
tags: [],
|
24
24
|
notes: '',
|
25
25
|
name: '',
|
26
|
-
template_path: nil
|
26
|
+
template_path: nil,
|
27
|
+
unsafe_options: []
|
27
28
|
}
|
28
29
|
end
|
29
30
|
|
@@ -43,8 +44,6 @@ module AsanaExceptionNotifier
|
|
43
44
|
return unless io.respond_to?(:rewind)
|
44
45
|
io.rewind
|
45
46
|
io.read
|
46
|
-
rescue
|
47
|
-
io.inspect
|
48
47
|
end
|
49
48
|
|
50
49
|
def tempfile_details(tempfile)
|
@@ -120,8 +119,7 @@ module AsanaExceptionNotifier
|
|
120
119
|
end
|
121
120
|
|
122
121
|
def template_path_exist(path)
|
123
|
-
|
124
|
-
fail ArgumentError, "file #{path} doesn't exist"
|
122
|
+
File.exist?(path)
|
125
123
|
end
|
126
124
|
|
127
125
|
def get_hash_rows(hash, rows = [], prefix = '')
|
@@ -129,7 +127,7 @@ module AsanaExceptionNotifier
|
|
129
127
|
if value.is_a?(Hash)
|
130
128
|
get_hash_rows(value, rows, key)
|
131
129
|
else
|
132
|
-
rows.push(["#{prefix}#{key}".inspect, escape(
|
130
|
+
rows.push(["#{prefix}#{key}".inspect, escape(value.inspect)])
|
133
131
|
end
|
134
132
|
end
|
135
133
|
rows
|
@@ -143,9 +141,10 @@ module AsanaExceptionNotifier
|
|
143
141
|
text.gsub('&', '&').gsub('<', '<').gsub('>', '>')
|
144
142
|
end
|
145
143
|
|
146
|
-
def set_fieldset_key(links, prefix)
|
147
|
-
|
148
|
-
|
144
|
+
def set_fieldset_key(links, prefix, default)
|
145
|
+
prefix_name = prefix.present? ? prefix : default
|
146
|
+
links[prefix_name] ||= {}
|
147
|
+
prefix_name
|
149
148
|
end
|
150
149
|
|
151
150
|
def parse_fieldset_value(options)
|
@@ -153,6 +152,14 @@ module AsanaExceptionNotifier
|
|
153
152
|
value.is_a?(Hash) ? value.reject! { |_new_key, new_value| new_value.is_a?(Hash) } : value
|
154
153
|
end
|
155
154
|
|
155
|
+
def coerce_object_to_hash(object)
|
156
|
+
hash = {}
|
157
|
+
object.instance_variables.each do |name|
|
158
|
+
hash[name.to_s[1..-1]] = object.instance_variable_get(name)
|
159
|
+
end
|
160
|
+
hash
|
161
|
+
end
|
162
|
+
|
156
163
|
# Mount table for hash, using name and value and adding a name_value class
|
157
164
|
# to the generated table.
|
158
165
|
#
|
@@ -168,6 +175,19 @@ module AsanaExceptionNotifier
|
|
168
175
|
end.join(' ')
|
169
176
|
end
|
170
177
|
|
178
|
+
def remove_blank(args)
|
179
|
+
args.delete_if { |_key, value| value.blank? } if args.is_a?(Hash)
|
180
|
+
args.reject!(&:blank?) if args.is_a?(Array)
|
181
|
+
end
|
182
|
+
|
183
|
+
def get_table_headers(header)
|
184
|
+
header.map { |name| escape(name.to_s.humanize) }.join('</th><th>')
|
185
|
+
end
|
186
|
+
|
187
|
+
def get_table_rows(array)
|
188
|
+
array.map { |name| "<tr><td>#{name.join('</td><td>')}</td></tr>" }.join
|
189
|
+
end
|
190
|
+
|
171
191
|
# returns the root path of the gem
|
172
192
|
#
|
173
193
|
# @return [void]
|
@@ -13,16 +13,11 @@ module AsanaExceptionNotifier
|
|
13
13
|
# The first array is used as label.
|
14
14
|
#
|
15
15
|
def mount_table(array, options = {})
|
16
|
-
|
17
|
-
header = array.shift
|
18
|
-
|
19
|
-
header = header.map { |name| escape(name.to_s.humanize) }
|
20
|
-
rows = array.map { |name| "<tr><td>#{name.join('</td><td>')}</td></tr>" }
|
21
|
-
|
16
|
+
header = array.extract_options!
|
22
17
|
<<-HTML
|
23
18
|
<table #{hash_to_html_attributes(options)}>
|
24
|
-
<thead><tr><th>#{header
|
25
|
-
<tbody>#{
|
19
|
+
<thead><tr><th>#{get_table_headers(header)}</th></tr></thead>
|
20
|
+
<tbody>#{get_table_rows(array)}</tbody>
|
26
21
|
</table>
|
27
22
|
HTML
|
28
23
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: asana_exception_notifier
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- bogdanRada
|
@@ -419,6 +419,7 @@ files:
|
|
419
419
|
- lib/asana_exception_notifier.rb
|
420
420
|
- lib/asana_exception_notifier/classes/asana.rb
|
421
421
|
- lib/asana_exception_notifier/classes/error_page.rb
|
422
|
+
- lib/asana_exception_notifier/classes/unsafe_filter.rb
|
422
423
|
- lib/asana_exception_notifier/helpers/application_helper.rb
|
423
424
|
- lib/asana_exception_notifier/helpers/heredoc_helper.rb
|
424
425
|
- lib/asana_exception_notifier/initializers/zip.rb
|