redmine_airbrake_backend 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a4627e9e6862c801b73cf31178ff43d50ba40fae
4
- data.tar.gz: 0205349f0793115c48e62bdfd85401903ff94421
3
+ metadata.gz: 7fced1efea4d537b27f9a4a741aaf307a22718bf
4
+ data.tar.gz: dcbedce9d1f9abdcd109ae1cec7c15b4f33702c5
5
5
  SHA512:
6
- metadata.gz: 8f50e28e27bb16e93c8d1dbf56c24f0d049d7c7e9133f70170d47536c9e0eadd0c2c359c372dc7497c52f2d7d64d95ab47ca302fec5899d42e69566b03d1f844
7
- data.tar.gz: 5d086483a614240d063d1cd04617b4aa71733bc731ead73051499011ddced147ce72af47a691fc4cbabdee62e835c4f093b976defe7ea2a962ef1e227d1c3e3f
6
+ metadata.gz: 5431defd44ddd91e10b3b052a93ca98afea49629a45612f2e7d15242baa3e76d4d4b69268084d71dddfad80559d48a461fdaacff36734f940c2ab7caec32a3c9
7
+ data.tar.gz: c4195a878a5fd1fba3e90eddfa1ffb44e314122d587c854bcd594ecccc986a93b6089a4e43521e39773a6232347c81d1f0990bcbbe769f3958c5036edc473c95
data/CHANGELOG.md CHANGED
@@ -1,6 +1,11 @@
1
1
  # Changelog
2
2
 
3
- ## Unreleased
3
+ ## 1.0.1 (2016-01-25)
4
+ ### Fixes
5
+ - Add space to comma separated key-value list in description tables
6
+ - Exclude notifier information from context table
7
+
8
+ ## 1.0.0 (2016-01-23)
4
9
  ### Changes
5
10
  - Add support for new v3 JSON notices
6
11
  - Add support for new v3 JSON iOS reports
data/README.md CHANGED
@@ -33,6 +33,7 @@ Please see http://www.redmine.org/projects/redmine/wiki/Plugins for installation
33
33
  4. Check if the custom fields are assigned to the trackers you want to use with airbrake
34
34
  5. Enable the project module (Airbrake) in your project settings (don't forget to add at least the Airbrake notice ID custom field to your project if it is not a global field)
35
35
  6. Configure additional defaults under the settings tab per project (Airbrake)
36
+ 6. Check if the user used for airbrake has a role with the _Airbrake_ permission
36
37
 
37
38
  ## Client configuration
38
39
 
@@ -8,6 +8,7 @@ class AirbrakeController < ::ApplicationController
8
8
 
9
9
  skip_before_action :verify_authenticity_token
10
10
 
11
+ prepend_before_action :load_records
11
12
  prepend_before_action :parse_key
12
13
  prepend_before_action :find_project
13
14
  before_action :set_environment
@@ -27,15 +28,20 @@ class AirbrakeController < ::ApplicationController
27
28
  @key = JSON.parse(params[:key]).symbolize_keys #rescue nil
28
29
 
29
30
  # API key
30
- raise InvalidRequest.new('No or invalid API key') if @key.blank? || @key[:key].blank?
31
+ invalid_request!('No or invalid API key') if @key.blank? || @key[:key].blank?
31
32
  params[:key] = @key[:key]
32
33
 
34
+ # Type
35
+ @type = @key[:type] || (params[:context][:language].split('/', 2).first.downcase rescue nil)
36
+ end
37
+
38
+ def load_records
33
39
  # Tracker
34
40
  @tracker = record_for(@project.trackers, :tracker)
35
- raise InvalidRequest.new('No or invalid tracker') if @tracker.blank?
41
+ invalid_request!('No or invalid tracker') if @tracker.blank?
36
42
 
37
43
  # Notice ID field
38
- raise InvalidRequest.new('Custom field for notice hash not available on selected tracker') if @tracker.custom_fields.find_by(id: notice_hash_field.id).blank?
44
+ invalid_request!('Custom field for notice hash not available on selected tracker') if @tracker.custom_fields.find_by(id: notice_hash_field.id).blank?
39
45
 
40
46
  # Category
41
47
  @category = record_for(@project.issue_categories, :category)
@@ -48,13 +54,14 @@ class AirbrakeController < ::ApplicationController
48
54
 
49
55
  # Repository
50
56
  @repository = @project.repositories.find_by(identifier: (@key[:repository] || ''))
51
-
52
- # Type
53
- @type = @key[:type] || (params[:context][:language].split('/', 2).first.downcase rescue nil)
54
57
  end
55
58
 
56
59
  def set_environment
57
- @environment = params[:context][:environment].presence rescue nil
60
+ @environment ||= params[:context][:environment].presence rescue nil
61
+ end
62
+
63
+ def invalid_request!(message)
64
+ raise InvalidRequest.new(message)
58
65
  end
59
66
 
60
67
  def render_bad_request(error)
@@ -63,6 +70,17 @@ class AirbrakeController < ::ApplicationController
63
70
  render text: error.message, status: :bad_request
64
71
  end
65
72
 
73
+ def render_airbrake_response
74
+ if @issue.present?
75
+ render json: {
76
+ id: (CustomValue.find_by(customized_type: Issue.name, customized_id: @issue.id, custom_field_id: notice_hash_field.id).value rescue nil),
77
+ url: issue_url(@issue)
78
+ }
79
+ else
80
+ render json: {}
81
+ end
82
+ end
83
+
66
84
  def record_for(on, key, fields = [:id, :name])
67
85
  fields.each do |field|
68
86
  val = on.find_by(field => @key[key])
@@ -4,8 +4,14 @@ class AirbrakeNoticeController < ::AirbrakeController
4
4
 
5
5
  # Handle airbrake notices
6
6
  def notices
7
- @issue = nil
7
+ create_issues
8
8
 
9
+ render_airbrake_response
10
+ end
11
+
12
+ private
13
+
14
+ def create_issues
9
15
  params[:errors].each do |e|
10
16
  error = RedmineAirbrakeBackend::Error.new(e)
11
17
 
@@ -17,14 +23,5 @@ class AirbrakeNoticeController < ::AirbrakeController
17
23
 
18
24
  @issue ||= issue if issue.save
19
25
  end
20
-
21
- if @issue.present?
22
- render json: {
23
- id: (CustomValue.find_by(customized_type: Issue.name, customized_id: @issue.id, custom_field_id: notice_hash_field.id).value rescue nil),
24
- url: issue_url(@issue)
25
- }
26
- else
27
- render json: {}
28
- end
29
26
  end
30
27
  end
@@ -7,6 +7,14 @@ class AirbrakeReportController < ::AirbrakeController
7
7
 
8
8
  # Handle airbrake iOS reports
9
9
  def ios_reports
10
+ create_issue
11
+
12
+ render_airbrake_response
13
+ end
14
+
15
+ private
16
+
17
+ def create_issue
10
18
  error = RedmineAirbrakeBackend::IosReport.new(params[:report])
11
19
 
12
20
  @issue = find_or_initialize_issue(error)
@@ -15,15 +23,6 @@ class AirbrakeReportController < ::AirbrakeController
15
23
 
16
24
  reopen_issue(@issue, error) if @issue.persisted? && @issue.status.is_closed? && reopen_issue?
17
25
 
18
- unless @issue.save
19
- render json: {}
20
-
21
- return
22
- end
23
-
24
- render json: {
25
- id: (CustomValue.find_by(customized_type: Issue.name, customized_id: @issue.id, custom_field_id: notice_hash_field.id).value rescue nil),
26
- url: issue_url(@issue)
27
- }
26
+ @issue = nil unless @issue.save
28
27
  end
29
28
  end
@@ -8,7 +8,7 @@ module AirbrakeHelper
8
8
  if value.is_a?(String)
9
9
  lines << "|@#{key}@|@#{value}@|"
10
10
  elsif value.is_a?(Hash)
11
- lines << "|@#{key}@|@#{value.map { |k, v| "#{k}: #{v}"}.join(',')}@|"
11
+ lines << "|@#{key}@|@#{value.map { |k, v| "#{k}: #{v}"}.join(', ')}@|"
12
12
  end
13
13
  end
14
14
  lines.join("\n")
@@ -33,7 +33,7 @@ h2. Session
33
33
  <% if params[:context].present? %>
34
34
  h2. Context
35
35
 
36
- <%= format_table(params[:context].reject { |k, v| [:notifier].include?(k) }) %>
36
+ <%= format_table(params[:context].reject { |k, v| ['notifier'].include?(k) }) %>
37
37
  <% end %>
38
38
 
39
39
 
@@ -25,7 +25,7 @@ module RedmineAirbrakeBackend
25
25
  @subject = generate_subject
26
26
 
27
27
  # Attachments
28
- @attachments = data[:attachments].presence || []
28
+ @attachments = (data[:attachments].presence || []).compact
29
29
 
30
30
  # Application
31
31
  @application = data[:application].presence
@@ -25,51 +25,19 @@ module RedmineAirbrakeBackend
25
25
  data.split("\n").each do |line|
26
26
  header_finished = true if line =~ /^(Application Specific Information|Last Exception Backtrace|Thread \d+( Crashed)?):$/
27
27
 
28
- unless header_finished
29
- key, value = line.split(':', 2).map { |s| s.strip }
30
-
31
- next if key.blank? || value.blank?
32
-
33
- case key
34
- when 'Exception Type'
35
- error[:type] = value
36
- when 'Exception Codes'
37
- error[:message] = value
38
- when 'Incident Identifier'
39
- indicent_identifier = value
40
- when 'Identifier'
41
- error[:application][:name] = value
42
- when 'Version'
43
- error[:application][:version] = value
44
- end
45
- end
28
+ indicent_identifier = parse_header_line(line, error) unless header_finished
46
29
 
47
30
  if next_line_is_message
48
31
  next_line_is_message = false
49
32
 
50
- error[:message] = line
51
-
52
- if line =~ /^\*\*\* Terminating app due to uncaught exception '([^']+)', reason: '\*\*\* (.*)'$/
53
- error[:type] = Regexp.last_match(1)
54
- error[:message] = Regexp.last_match(2)
55
- else
56
- error[:message] = line
57
- end
33
+ parse_message(line, error)
58
34
  end
59
35
 
60
36
  crashed_thread = false if line =~ /^Thread \d+:$/
61
37
 
62
- if crashed_thread
63
- if line =~ /^(\d+)\s+([^\s]+)\s+(0x[0-9a-f]+)\s+(.+) \+ (\d+)$/
64
- error[:backtrace] << {
65
- file: Regexp.last_match(2),
66
- function: Regexp.last_match(4),
67
- line: Regexp.last_match(5)
68
- }
69
- end
70
- end
38
+ error[:backtrace] << parse_backtrace_element(line) if crashed_thread
71
39
 
72
- crashed_thread = true if error[:backtrace].blank? && line =~ /^(Last Exception Backtrace|Thread \d+ Crashed):$/
40
+ crashed_thread = true if error[:backtrace].compact.blank? && line =~ /^(Last Exception Backtrace|Thread \d+ Crashed):$/
73
41
 
74
42
  next_line_is_message = true if line =~ /^Application Specific Information:$/
75
43
  end
@@ -83,5 +51,49 @@ module RedmineAirbrakeBackend
83
51
 
84
52
  error
85
53
  end
54
+
55
+ def self.parse_header_line(line, error)
56
+ key, value = line.split(':', 2).map { |s| s.strip }
57
+
58
+ next if key.blank? || value.blank?
59
+
60
+ case key
61
+ when 'Exception Type'
62
+ error[:type] = value
63
+ when 'Exception Codes'
64
+ error[:message] = value
65
+ when 'Incident Identifier'
66
+ return value
67
+ when 'Identifier'
68
+ error[:application][:name] = value
69
+ when 'Version'
70
+ error[:application][:version] = value
71
+ end
72
+
73
+ nil
74
+ end
75
+
76
+ def self.parse_message(line, error)
77
+ error[:message] = line
78
+
79
+ if line =~ /^\*\*\* Terminating app due to uncaught exception '([^']+)', reason: '\*\*\* (.*)'$/
80
+ error[:type] = Regexp.last_match(1)
81
+ error[:message] = Regexp.last_match(2)
82
+ else
83
+ error[:message] = line
84
+ end
85
+ end
86
+
87
+ def self.parse_backtrace_element(line)
88
+ if line =~ /^(\d+)\s+([^\s]+)\s+(0x[0-9a-f]+)\s+(.+) \+ (\d+)$/
89
+ {
90
+ file: Regexp.last_match(2),
91
+ function: Regexp.last_match(4),
92
+ line: Regexp.last_match(5)
93
+ }
94
+ else
95
+ nil
96
+ end
97
+ end
86
98
  end
87
99
  end
@@ -1,4 +1,4 @@
1
1
  module RedmineAirbrakeBackend
2
2
  # Version of this gem
3
- VERSION = '1.0.0'
3
+ VERSION = '1.0.1'
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redmine_airbrake_backend
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Florian Schwab
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-23 00:00:00.000000000 Z
11
+ date: 2016-01-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails