recuperar el código fuente

This commit is contained in:
f 2021-03-20 13:43:31 -03:00
parent 8cf5d92dae
commit 496d30807f

View file

@ -12,7 +12,7 @@ class BacktraceJob < ApplicationJob
@site_id = site_id @site_id = site_id
@params = params @params = params
unless files.empty? unless sources.empty?
params['errors'].each do |error| params['errors'].each do |error|
error['backtrace'].each do |backtrace| error['backtrace'].each do |backtrace|
offset = SourceMap::Offset.new(backtrace['line'], backtrace['column']) offset = SourceMap::Offset.new(backtrace['line'], backtrace['column'])
@ -20,9 +20,15 @@ class BacktraceJob < ApplicationJob
next unless mapping next unless mapping
data = data(backtrace['file'])
backtrace['file'] = mapping.source backtrace['file'] = mapping.source
backtrace['line'] = mapping.original.line backtrace['line'] = mapping.original.line
backtrace['column'] = mapping.original.column backtrace['column'] = mapping.original.column
# Encuentra el código fuente del error
source = data.dig('sourcesContent', data['sources']&.index(backtrace['file']))&.split("\n")
backtrace['function'] = source.dig(backtrace['line'] - 1) if source.present?
end end
end end
end end
@ -40,15 +46,33 @@ class BacktraceJob < ApplicationJob
@site ||= Site.find_by_id(site_id) @site ||= Site.find_by_id(site_id)
end end
# Obtiene todos los archivos del backtrace # Obtiene todos los archivos del backtrace solo si los puede descargar
def files # desde fuentes seguras.
@files ||= params['errors'].map do |x| #
x['backtrace'] # XXX: Idealmente no trabajamos con recursos externos, pero en este
end.flatten.map do |x| # momento no podemos saber todas las URLs de un sitio y quizás nunca
x['file'].split('@').last # lo sabremos :B
end.uniq.select do |x| def sources
x&.start_with?(site.url) @sources ||= params['errors'].map do |x|
end x['backtrace']
end.flatten.map do |x|
x['file'].split('@').last
end.uniq.select do |x|
%r{\Ahttps://} =~ x
end
end
# Descarga y devuelve los datos de un archivo
#
# @param [String] La URL del map
# @return [Hash]
def data(map)
map += '.map' unless map.end_with? '.map'
@data ||= {}
@data[map] ||= FastJsonparser.parse(Rails.cache.fetch(map, expires_in: 12.hours) do
Down.open(map).read
end, symbolize_keys: false)
end end
# Asume que todos los sourcemaps comparten la misma URL, lo # Asume que todos los sourcemaps comparten la misma URL, lo
@ -56,15 +80,13 @@ class BacktraceJob < ApplicationJob
# archivo. # archivo.
# #
# Descarga los archivos y obtiene el backtrace original. # Descarga los archivos y obtiene el backtrace original.
#
# @return [SourceMap::Map]
def sourcemap def sourcemap
@sourcemap ||= @sourcemap ||=
begin begin
files.map { |x| "#{x}.map" }.map do |x| sources.map { |x| "#{x}.map" }.map do |map|
data = FastJsonparser.parse(Rails.cache.fetch(x, expires_in: 12.hours) do SourceMap::Map.from_hash data(map)
Down.open(x).read
end, symbolize_keys: false)
SourceMap::Map.from_hash data
rescue Down::Error, FastJsonparser::Error rescue Down::Error, FastJsonparser::Error
SourceMap::Map.new SourceMap::Map.new
end.reduce(&:+) end.reduce(&:+)