-
Notifications
You must be signed in to change notification settings - Fork 283
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Users can decide to send the `code` and `context` data for the sent exception frames, so they can easier see in the Rollbar site what happened and where. This feature is configurable using `config.send_extra_frame_data` which can have three values: `:none` (defualt), `:app` and `:all`. Using `:app`, only the `code` and `context` for the project code frames will be sent, and all of them if used `all`. Example: ```ruby Rollbar.configure do |config| # ... config.send_extra_frame_data = :app end ```
- Loading branch information
Jon de Andres
committed
Sep 13, 2016
1 parent
374eb9e
commit d17f244
Showing
7 changed files
with
460 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
# We want to use Gem.path | ||
require 'rubygems' | ||
|
||
module Rollbar | ||
class Item | ||
# Representation of the trace data per frame in the payload | ||
class Frame | ||
attr_reader :backtrace | ||
attr_reader :frame | ||
attr_reader :configuration | ||
|
||
MAX_CONTEXT_LENGTH = 4 | ||
|
||
def initialize(backtrace, frame, options = {}) | ||
@backtrace = backtrace | ||
@frame = frame | ||
@configuration = options[:configuration] | ||
end | ||
|
||
def to_h | ||
# parse the line | ||
match = frame.match(/(.*):(\d+)(?::in `([^']+)')?/) | ||
|
||
return unknown_frame unless match | ||
|
||
filename = match[1] | ||
lineno = match[2].to_i | ||
frame_data = { | ||
:filename => filename, | ||
:lineno => lineno, | ||
:method => match[3] | ||
} | ||
|
||
frame_data.merge(extra_frame_data(filename, lineno)) | ||
end | ||
|
||
private | ||
|
||
def unknown_frame | ||
{ :filename => '<unknown>', :lineno => 0, :method => frame } | ||
end | ||
|
||
def extra_frame_data(filename, lineno) | ||
file_lines = backtrace.get_file_lines(filename) | ||
|
||
return {} if skip_extra_frame_data?(filename, file_lines) | ||
|
||
{ | ||
:code => code_data(file_lines, lineno), | ||
:context => context_data(file_lines, lineno) | ||
} | ||
end | ||
|
||
def skip_extra_frame_data?(filename, file_lines) | ||
config = configuration.send_extra_frame_data | ||
missing_file_lines = !file_lines || file_lines.empty? | ||
|
||
return false if !missing_file_lines && config == :all | ||
|
||
missing_file_lines || | ||
config == :none || | ||
config == :app && outside_project?(filename) | ||
end | ||
|
||
def outside_project?(filename) | ||
project_gem_paths = configuration.project_gem_paths | ||
inside_project_gem_paths = project_gem_paths.any? do |path| | ||
filename.start_with?(path) | ||
end | ||
|
||
# The file is inside the configuration.project_gem_paths, | ||
return false if inside_project_gem_paths | ||
|
||
root = configuration.root | ||
inside_root = root && filename.start_with?(root.to_s) | ||
|
||
# The file is outside the configuration.root | ||
return true unless inside_root | ||
|
||
# At this point, the file is inside the configuration.root. | ||
# Since it's common to have gems installed in {root}/vendor/bundle, | ||
# let's check it's in any of the Gem.path paths | ||
Gem.path.any? { |path| filename.start_with?(path) } | ||
end | ||
|
||
def code_data(file_lines, lineno) | ||
file_lines[lineno - 1] | ||
end | ||
|
||
def context_data(file_lines, lineno) | ||
{ | ||
:pre => pre_data(file_lines, lineno), | ||
:post => post_data(file_lines, lineno) | ||
} | ||
end | ||
|
||
def post_data(file_lines, lineno) | ||
from_line = lineno | ||
number_of_lines = [from_line + MAX_CONTEXT_LENGTH, file_lines.size].min - from_line | ||
|
||
file_lines[from_line, number_of_lines] | ||
end | ||
|
||
def pre_data(file_lines, lineno) | ||
to_line = lineno - 2 | ||
from_line = [to_line - MAX_CONTEXT_LENGTH + 1, 0].max | ||
|
||
file_lines[from_line, (to_line - from_line + 1)].select(&:present?) | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
require 'spec_helper' | ||
require 'tempfile' | ||
require 'rollbar/item/backtrace' | ||
|
||
describe Rollbar::Item::Backtrace do | ||
describe '#get_file_lines' do | ||
subject { described_class.new(exception) } | ||
|
||
let(:exception) { Exception.new } | ||
let(:file) { Tempfile.new('foo') } | ||
|
||
before do | ||
File.open(file.path, 'w') do |f| | ||
f << "foo\nbar" | ||
end | ||
end | ||
|
||
it 'returns the lines of the file' do | ||
lines = subject.get_file_lines(file.path) | ||
|
||
expect(lines.size).to be_eql(2) | ||
expect(lines[0]).to be_eql('foo') | ||
expect(lines[1]).to be_eql('bar') | ||
end | ||
end | ||
end |
Oops, something went wrong.