asana_exception_notifier 0.0.3 → 0.0.4

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
  SHA1:
3
- metadata.gz: 26a4963df2fedaa47495a14337cbb79a4deb632a
4
- data.tar.gz: 0a2839dd8fab800fb2fd33f365a1c0c910e8f519
3
+ metadata.gz: 3e9dd8cc08308fa3e912aa23314f1a5edd2d9f3e
4
+ data.tar.gz: 5b7599db7a424495bad6ceb7f32d78e577c86c78
5
5
  SHA512:
6
- metadata.gz: d68837acda0f936813c94c873bbdcf16f4cd1c033aee92545daeddfc7617340e4232ccc6baea919d873f60902b7ae8057186dcc184074c775ba1a02fbfc80043
7
- data.tar.gz: cc7f630304a094a868a35a9d06ccf0914b45487e226ea20bfc5c845b04f50d04eaeec85dc797abb3d607b0d7a394c976fe37166776371512672ce9d18d1597cc
6
+ metadata.gz: a1754feadb154011e8e833dee9456b8ba3beee6d7b5d41defb2ad6fed35ce4743926c0af8acd1e0757da652be07e46d98df61572711cf18be49187dd98666987
7
+ data.tar.gz: 66efa3e2561928c8de2b64a7a0ec77a407940f2e5634fb0864ea5dd6cc41ee23d76e08fe64d2a9fc28cee772e586971b6a6c291fdffa41aff060aba6d7880b40
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- asana_exception_notifier (0.0.1)
4
+ asana_exception_notifier (0.0.4)
5
5
  activesupport (>= 4.0, < 5)
6
6
  em-http-request (~> 1.1, >= 1.1.2)
7
7
  eventmachine (~> 1.0, >= 1.0.7)
data/README.md CHANGED
@@ -8,7 +8,7 @@ Description
8
8
 
9
9
  Simple ruby implementation to send notifications to Asana when a exception happens in Rails or Rack-based apps by creating a task and uploading exception details to the task
10
10
 
11
- The gem provides a notifier for sending notifications to Asana when errors occur in a Rack/Rails application [courtesy of exception_notifications gem](https://github.com/smartinez87/exception_notifications). Check out that gem for more details on setting up the rack middleware with additional options.
11
+ The gem provides a notifier for sending notifications to Asana when errors occur in a Rack/Rails application [courtesy of exception_notification gem](https://github.com/smartinez87/exception_notification). Check out that gem for more details on setting up the rack middleware with additional options.
12
12
 
13
13
  Requirements
14
14
  ------------
@@ -15,15 +15,14 @@ module ExceptionNotifier
15
15
  def initialize(options)
16
16
  execute_with_rescue do
17
17
  super
18
- @initial_options = options.symbolize_keys
19
- options = @initial_options.reject { |_key, value| value.blank? }
20
- parse_options(options)
18
+ @initial_options = options.symbolize_keys.reject { |_key, value| value.blank? }
19
+ parse_options(@initial_options)
21
20
  end
22
21
  end
23
22
 
24
23
  def call(exception, options = {})
25
- execute_with_rescue do
26
- ensure_eventmachine_running do
24
+ ensure_eventmachine_running do
25
+ execute_with_rescue do
27
26
  EM::HttpRequest.use AsanaExceptionNotifier::Request::Middleware if ENV['DEBUG_ASANA_EXCEPTION_NOTIFIER']
28
27
  error_page = AsanaExceptionNotifier::ErrorPage.new(template_path, exception, options)
29
28
  create_asana_task(error_page) if active?
@@ -31,27 +30,54 @@ module ExceptionNotifier
31
30
  end
32
31
  end
33
32
 
33
+ def asana_api_key
34
+ @default_options.fetch(:asana_api_key, nil)
35
+ end
36
+
37
+ def workspace
38
+ @default_options.fetch(:workspace, nil)
39
+ end
40
+
41
+ def notes
42
+ @default_options.fetch(:notes, nil)
43
+ end
44
+
45
+ def task_name
46
+ @default_options.fetch(:name, nil)
47
+ end
48
+
34
49
  def active?
35
- @default_options.fetch(:asana_api_key, nil).present? && @default_options.fetch(:workspace, nil).present?
50
+ asana_api_key.present? && workspace.present?
51
+ end
52
+
53
+ def template_path
54
+ @default_options.fetch(:template_path, nil)
36
55
  end
37
56
 
38
57
  private
39
58
 
40
59
  def parse_options(options)
41
- options = options.symbolize_keys.reject { |key, _value| !permitted_options.key?(key) }
60
+ options = options.reject { |key, _value| !permitted_options.key?(key) }
42
61
  @default_options = permitted_options.merge(options).reject { |_key, value| value.blank? }
43
62
  end
44
63
 
45
- def template_path
46
- template_path = @default_options.fetch(:template_path, nil)
47
- template_path.blank? ? default_template_path : template_path_exist(File.expand_path(template_path))
64
+ def note_content(error_page)
65
+ if path_is_a_template?(notes)
66
+ error_page.render_template(expanded_path(notes))
67
+ else
68
+ notes.present? ? notes : error_page.render_template(File.join(template_dir, 'notes.text.erb'))
69
+ end
70
+ end
71
+
72
+ def task_name_content(error_page)
73
+ task_name.present? ? task_name : "[AsanaExceptionNotifier] #{error_page.exception_data[:message]}"
48
74
  end
49
75
 
50
76
  def build_request_options(error_page)
51
77
  @default_options.except(:asana_api_key, :template_path).merge(
52
- name: @default_options.fetch(:name, nil) || "[AsanaExceptionNotifier] #{error_page.exception_data[:message]}",
53
- notes: @default_options.fetch(:notes, nil) || error_page.render_template(File.join(template_dir, 'asana_exception_notifier.text.erb')),
54
- workspace: @default_options.fetch(:workspace, nil).to_i
78
+ name: task_name_content(error_page),
79
+ notes: note_content(error_page),
80
+ workspace: workspace.to_i
55
81
  ).symbolize_keys!
56
82
  end
57
83
 
@@ -7,9 +7,9 @@ module AsanaExceptionNotifier
7
7
  attr_reader :template_path, :exception, :options, :boundary, :template_details, :env, :request, :tempfile, :template_params, :content
8
8
 
9
9
  def initialize(template_path, exception, options)
10
- @template_path = template_path
11
10
  @exception = exception
12
11
  @options = options.symbolize_keys
12
+ html_template(template_path)
13
13
  @template_details = setup_template_details
14
14
  @env = (@options[:env] || ENV.to_h).stringify_keys
15
15
  @request = action_dispatch? ? ActionDispatch::Request.new(@env) : Rack::Request.new(@env)
@@ -17,6 +17,14 @@ module AsanaExceptionNotifier
17
17
  parse_exception_options
18
18
  end
19
19
 
20
+ def html_template(path)
21
+ @template_path = if path_is_a_template?(path)
22
+ expanded_path(path)
23
+ else
24
+ File.join(template_dir, 'exception_details.html.erb')
25
+ end
26
+ end
27
+
20
28
  def action_dispatch?
21
29
  defined?(ActionDispatch::Request)
22
30
  end
@@ -110,17 +118,19 @@ module AsanaExceptionNotifier
110
118
  def create_tempfile(output = render_template)
111
119
  tempfile = Tempfile.new([SecureRandom.uuid, ".#{@template_details[:template_extension]}"], encoding: 'utf-8')
112
120
  tempfile.write(output)
121
+ ObjectSpace.undefine_finalizer(tempfile) # force garbage collector not to remove automatically the file
113
122
  tempfile.close
114
- details = tempfile_details(tempfile)
115
- [details[:filename], details[:path]]
123
+ tempfile_details(tempfile).slice(:filename, :path).values
116
124
  end
117
125
 
118
126
  def fetch_archives(output = render_template)
119
- return [] if output.blank?
120
- filename, path = create_tempfile(output)
121
- archive = compress_files(File.dirname(path), filename, [path])
122
- remove_tempfile(path)
123
- split_archive(archive, "part_#{filename}", 1024 * 1024 * 100)
127
+ execute_with_rescue(value: []) do
128
+ return [] if output.blank?
129
+ filename, path = create_tempfile(output)
130
+ archive = compress_files(File.dirname(path), filename, [expanded_path(path)])
131
+ remove_tempfile(path)
132
+ split_archive(archive, "part_#{filename}", 1024 * 1024 * 100)
133
+ end
124
134
  end
125
135
 
126
136
  def remove_tempfile(path)
@@ -1,6 +1,8 @@
1
+ require_relative './heredoc_helper'
1
2
  module AsanaExceptionNotifier
2
3
  # module that is used for formatting numbers using metrics
3
4
  module ApplicationHelper
5
+ include AsanaExceptionNotifier::HeredocHelper
4
6
  # function that makes the methods incapsulated as utility functions
5
7
 
6
8
  module_function
@@ -21,25 +23,28 @@ module AsanaExceptionNotifier
21
23
  tags: [],
22
24
  notes: '',
23
25
  name: '',
24
- template_path: default_template_path
26
+ template_path: nil
25
27
  }
26
28
  end
27
29
 
30
+ def expanded_path(path)
31
+ File.expand_path(path)
32
+ end
33
+
34
+ def path_is_a_template?(path)
35
+ path.present? && template_path_exist(expanded_path(path))
36
+ end
37
+
28
38
  def multi_request_manager
29
39
  @multi_manager ||= EventMachine::MultiRequest.new
30
40
  end
31
41
 
32
- def extract_body(env)
33
- return if env.blank? || !env.is_a?(Hash)
34
- io = env['rack.input']
35
- io.rewind if io.respond_to?(:rewind)
42
+ def extract_body(io)
43
+ return unless io.respond_to?(:rewind)
44
+ io.rewind
36
45
  io.read
37
- end
38
-
39
- def show_hash_content(hash)
40
- hash.map do |key, value|
41
- value.is_a?(Hash) ? show_hash_content(value) : ["#{key}:", value]
42
- end.join("\n ")
46
+ rescue
47
+ io.inspect
43
48
  end
44
49
 
45
50
  def tempfile_details(tempfile)
@@ -111,11 +116,7 @@ module AsanaExceptionNotifier
111
116
  end
112
117
 
113
118
  def template_dir
114
- File.expand_path(File.join(root, 'note_templates'))
115
- end
116
-
117
- def default_template_path
118
- File.join(template_dir, 'asana_exception_notifier.html.erb')
119
+ File.expand_path(File.join(root, 'templates'))
119
120
  end
120
121
 
121
122
  def template_path_exist(path)
@@ -123,26 +124,19 @@ module AsanaExceptionNotifier
123
124
  fail ArgumentError, "file #{path} doesn't exist"
124
125
  end
125
126
 
126
- def max_length(rows, index)
127
- value = rows.max_by { |array| array[index].to_s.size }
128
- value.is_a?(Array) ? value[index] : value
129
- end
130
-
131
127
  def get_hash_rows(hash, rows = [], prefix = '')
132
128
  hash.each do |key, value|
133
129
  if value.is_a?(Hash)
134
130
  get_hash_rows(value, rows, key)
135
131
  else
136
- rows.push(["#{prefix}#{key}".inspect, escape(value.inspect)])
132
+ rows.push(["#{prefix}#{key}".inspect, escape(inspect_value(value).inspect)])
137
133
  end
138
134
  end
139
135
  rows
140
136
  end
141
137
 
142
- def link_helper(link)
143
- <<-LINK
144
- <a href="javascript:void(0)" onclick="AjaxExceptionNotifier.hideAllAndToggle('#{link.downcase}')">#{link.camelize}</a>
145
- LINK
138
+ def inspect_value(value)
139
+ value.is_a?(IO) ? extract_body(value) : value
146
140
  end
147
141
 
148
142
  def escape(text)
@@ -159,24 +153,6 @@ module AsanaExceptionNotifier
159
153
  value.is_a?(Hash) ? value.reject! { |_new_key, new_value| new_value.is_a?(Hash) } : value
160
154
  end
161
155
 
162
- # Gets a bidimensional array and create a table.
163
- # The first array is used as label.
164
- #
165
- def mount_table(array, options = {})
166
- return '' if array.blank?
167
- header = array.shift
168
-
169
- header = header.map { |name| escape(name.to_s.humanize) }
170
- rows = array.map { |name| "<tr><td>#{name.join('</td><td>')}</td></tr>" }
171
-
172
- <<-TABLE
173
- <table #{hash_to_html_attributes(options)}>
174
- <thead><tr><th>#{header.join('</th><th>')}</th></tr></thead>
175
- <tbody>#{rows.join}</tbody>
176
- </table>
177
- TABLE
178
- end
179
-
180
156
  # Mount table for hash, using name and value and adding a name_value class
181
157
  # to the generated table.
182
158
  #
@@ -0,0 +1,30 @@
1
+ module AsanaExceptionNotifier
2
+ # helper methods that use Heredoc syntax
3
+ module HeredocHelper
4
+ module_function
5
+
6
+ def link_helper(link)
7
+ <<-HTML
8
+ <a href="javascript:void(0)" onclick="AjaxExceptionNotifier.hideAllAndToggle('#{link.downcase}')">#{link.camelize}</a>
9
+ HTML
10
+ end
11
+
12
+ # Gets a bidimensional array and create a table.
13
+ # The first array is used as label.
14
+ #
15
+ def mount_table(array, options = {})
16
+ return '' if array.blank?
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
+
22
+ <<-HTML
23
+ <table #{hash_to_html_attributes(options)}>
24
+ <thead><tr><th>#{header.join('</th><th>')}</th></tr></thead>
25
+ <tbody>#{rows.join}</tbody>
26
+ </table>
27
+ HTML
28
+ end
29
+ end
30
+ end
@@ -17,7 +17,7 @@ module AsanaExceptionNotifier
17
17
  # minor release version
18
18
  MINOR = 0
19
19
  # tiny release version
20
- TINY = 3
20
+ TINY = 4
21
21
  # prelease version ( set this only if it is a prelease)
22
22
  PRE = nil
23
23
 
@@ -3,7 +3,6 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe ExceptionNotifier::AsanaNotifier do
6
-
7
6
  let(:options) { double('options') }
8
7
 
9
8
  before(:each) do
@@ -18,6 +17,4 @@ describe ExceptionNotifier::AsanaNotifier do
18
17
  expect(@subject.initial_options).to eq options
19
18
  end
20
19
  end
21
-
22
-
23
20
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: asana_exception_notifier
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - bogdanRada
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-03 00:00:00.000000000 Z
11
+ date: 2016-02-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -420,12 +420,13 @@ files:
420
420
  - lib/asana_exception_notifier/classes/asana.rb
421
421
  - lib/asana_exception_notifier/classes/error_page.rb
422
422
  - lib/asana_exception_notifier/helpers/application_helper.rb
423
+ - lib/asana_exception_notifier/helpers/heredoc_helper.rb
423
424
  - lib/asana_exception_notifier/initializers/zip.rb
424
- - lib/asana_exception_notifier/note_templates/asana_exception_notifier.html.erb
425
- - lib/asana_exception_notifier/note_templates/asana_exception_notifier.text.erb
426
425
  - lib/asana_exception_notifier/request/client.rb
427
426
  - lib/asana_exception_notifier/request/core.rb
428
427
  - lib/asana_exception_notifier/request/middleware.rb
428
+ - lib/asana_exception_notifier/templates/exception_details.html.erb
429
+ - lib/asana_exception_notifier/templates/notes.text.erb
429
430
  - lib/asana_exception_notifier/version.rb
430
431
  - lib/generators/asana_exception_notifier/install_generator.rb
431
432
  - lib/generators/asana_exception_notifier/templates/asana_exception_notifier.rb