exception_hunter 0.1.1 → 0.4.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +35 -7
- data/app/assets/stylesheets/exception_hunter/base.css +62 -8
- data/app/assets/stylesheets/exception_hunter/errors.css +166 -24
- data/app/assets/stylesheets/exception_hunter/navigation.css +20 -5
- data/app/assets/stylesheets/exception_hunter/sessions.css +71 -0
- data/app/controllers/concerns/exception_hunter/authorization.rb +23 -0
- data/app/controllers/exception_hunter/application_controller.rb +2 -0
- data/app/controllers/exception_hunter/errors_controller.rb +27 -4
- data/app/controllers/exception_hunter/resolved_errors_controller.rb +11 -0
- data/app/helpers/exception_hunter/errors_helper.rb +7 -0
- data/app/helpers/exception_hunter/sessions_helper.rb +16 -0
- data/app/models/exception_hunter/application_record.rb +8 -0
- data/app/models/exception_hunter/error.rb +21 -8
- data/app/models/exception_hunter/error_group.rb +24 -5
- data/app/presenters/exception_hunter/dashboard_presenter.rb +54 -0
- data/app/presenters/exception_hunter/error_group_presenter.rb +25 -0
- data/app/presenters/exception_hunter/error_presenter.rb +10 -1
- data/app/views/exception_hunter/devise/sessions/new.html.erb +24 -0
- data/app/views/exception_hunter/errors/_error_row.erb +44 -0
- data/app/views/exception_hunter/errors/_error_summary.erb +23 -10
- data/app/views/exception_hunter/errors/_error_user_data.erb +4 -5
- data/app/views/exception_hunter/errors/_errors_table.erb +1 -0
- data/app/views/exception_hunter/errors/_last_7_days_errors_table.erb +12 -0
- data/app/views/exception_hunter/errors/index.html.erb +71 -30
- data/app/views/exception_hunter/errors/pagy/_pagy_nav.html.erb +15 -15
- data/app/views/exception_hunter/errors/show.html.erb +58 -22
- data/app/views/layouts/exception_hunter/application.html.erb +65 -6
- data/app/views/layouts/exception_hunter/exception_hunter_logged_out.html.erb +24 -0
- data/config/rails_best_practices.yml +2 -3
- data/config/routes.rb +19 -1
- data/lib/exception_hunter.rb +12 -2
- data/lib/exception_hunter/config.rb +8 -1
- data/lib/exception_hunter/devise.rb +17 -0
- data/lib/exception_hunter/engine.rb +5 -0
- data/{app/services → lib}/exception_hunter/error_creator.rb +17 -5
- data/lib/exception_hunter/error_reaper.rb +12 -0
- data/lib/exception_hunter/middleware/delayed_job_hunter.rb +69 -0
- data/lib/exception_hunter/middleware/request_hunter.rb +71 -0
- data/lib/exception_hunter/middleware/sidekiq_hunter.rb +59 -0
- data/lib/exception_hunter/tracking.rb +17 -0
- data/lib/exception_hunter/user_attributes_collector.rb +4 -0
- data/lib/exception_hunter/version.rb +1 -1
- data/lib/generators/exception_hunter/create_users/create_users_generator.rb +8 -1
- data/lib/generators/exception_hunter/install/install_generator.rb +3 -1
- data/lib/generators/exception_hunter/install/templates/create_exception_hunter_error_groups.rb.erb +3 -0
- data/lib/generators/exception_hunter/install/templates/exception_hunter.rb.erb +23 -0
- data/lib/tasks/exception_hunter_tasks.rake +6 -4
- metadata +25 -10
- data/config/initializers/exception_hunter.rb +0 -16
- data/lib/exception_hunter/railtie.rb +0 -11
- data/lib/exception_hunter/request_hunter.rb +0 -41
@@ -1,5 +1,12 @@
|
|
1
1
|
module ExceptionHunter
|
2
2
|
class Config
|
3
|
-
cattr_accessor :
|
3
|
+
cattr_accessor :admin_user_class,
|
4
|
+
:current_user_method, :user_attributes
|
5
|
+
cattr_accessor :enabled, default: true
|
6
|
+
cattr_accessor :errors_stale_time, default: 45.days
|
7
|
+
|
8
|
+
def self.auth_enabled?
|
9
|
+
admin_user_class.present? && admin_user_class.try(:underscore)
|
10
|
+
end
|
4
11
|
end
|
5
12
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module ExceptionHunter
|
2
|
+
module Devise
|
3
|
+
class SessionsController < ::Devise::SessionsController
|
4
|
+
skip_before_action :verify_authenticity_token
|
5
|
+
|
6
|
+
layout 'exception_hunter/exception_hunter_logged_out'
|
7
|
+
|
8
|
+
def after_sign_out_path_for(*)
|
9
|
+
'/exception_hunter/login'
|
10
|
+
end
|
11
|
+
|
12
|
+
def after_sign_in_path_for(*)
|
13
|
+
'/exception_hunter'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -12,5 +12,10 @@ module ExceptionHunter
|
|
12
12
|
app.config.assets.precompile << 'exception_hunter/application.css'
|
13
13
|
app.config.assets.precompile << 'exception_hunter/logo.png'
|
14
14
|
end
|
15
|
+
|
16
|
+
initializer 'exception_hunter.load_middleware', group: :all do
|
17
|
+
require 'exception_hunter/middleware/sidekiq_hunter' if defined?(Sidekiq)
|
18
|
+
require 'exception_hunter/middleware/delayed_job_hunter' if defined?(Delayed)
|
19
|
+
end
|
15
20
|
end
|
16
21
|
end
|
@@ -1,12 +1,18 @@
|
|
1
1
|
module ExceptionHunter
|
2
2
|
class ErrorCreator
|
3
|
+
HTTP_TAG = 'HTTP'.freeze
|
4
|
+
WORKER_TAG = 'Worker'.freeze
|
5
|
+
MANUAL_TAG = 'Manual'.freeze
|
6
|
+
|
3
7
|
class << self
|
4
|
-
def call(**error_attrs)
|
8
|
+
def call(tag: nil, **error_attrs)
|
9
|
+
return unless should_create?
|
10
|
+
|
5
11
|
ActiveRecord::Base.transaction do
|
6
12
|
error_attrs = extract_user_data(error_attrs)
|
7
|
-
error = Error.new(error_attrs)
|
8
|
-
error_group = ErrorGroup.find_matching_group(error) || ErrorGroup.new
|
9
|
-
update_error_group(error_group, error)
|
13
|
+
error = ::ExceptionHunter::Error.new(error_attrs)
|
14
|
+
error_group = ::ExceptionHunter::ErrorGroup.find_matching_group(error) || ::ExceptionHunter::ErrorGroup.new
|
15
|
+
update_error_group(error_group, error, tag)
|
10
16
|
error.error_group = error_group
|
11
17
|
error.save!
|
12
18
|
error
|
@@ -17,9 +23,15 @@ module ExceptionHunter
|
|
17
23
|
|
18
24
|
private
|
19
25
|
|
20
|
-
def
|
26
|
+
def should_create?
|
27
|
+
Config.enabled
|
28
|
+
end
|
29
|
+
|
30
|
+
def update_error_group(error_group, error, tag)
|
21
31
|
error_group.error_class_name = error.class_name
|
22
32
|
error_group.message = error.message
|
33
|
+
error_group.tags << tag unless tag.nil?
|
34
|
+
error_group.tags.uniq!
|
23
35
|
|
24
36
|
error_group.save!
|
25
37
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module ExceptionHunter
|
2
|
+
class ErrorReaper
|
3
|
+
class << self
|
4
|
+
def purge(stale_time: Config.errors_stale_time)
|
5
|
+
ActiveRecord::Base.transaction do
|
6
|
+
Error.with_occurrences_before(Date.today - stale_time).destroy_all
|
7
|
+
ErrorGroup.without_errors.destroy_all
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'delayed_job'
|
2
|
+
|
3
|
+
module ExceptionHunter
|
4
|
+
module Middleware
|
5
|
+
class DelayedJobHunter < ::Delayed::Plugin
|
6
|
+
TRACK_AT_RETRY = [0, 3, 6, 10].freeze
|
7
|
+
JOB_TRACKED_DATA = %w[
|
8
|
+
attempts
|
9
|
+
].freeze
|
10
|
+
ARGS_TRACKED_DATA = %w[
|
11
|
+
queue_name
|
12
|
+
job_class
|
13
|
+
job_id
|
14
|
+
arguments
|
15
|
+
enqueued_at
|
16
|
+
].freeze
|
17
|
+
|
18
|
+
callbacks do |lifecycle|
|
19
|
+
lifecycle.around(:invoke_job) do |job, *args, &block|
|
20
|
+
block.call(job, *args)
|
21
|
+
|
22
|
+
rescue Exception => exception # rubocop:disable Lint/RescueException
|
23
|
+
track_exception(exception, job)
|
24
|
+
|
25
|
+
raise exception
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.track_exception(exception, job)
|
30
|
+
return unless should_track?(job.attempts)
|
31
|
+
|
32
|
+
ErrorCreator.call(
|
33
|
+
tag: ErrorCreator::WORKER_TAG,
|
34
|
+
class_name: exception.class.to_s,
|
35
|
+
message: exception.message,
|
36
|
+
environment_data: environment_data(job),
|
37
|
+
backtrace: exception.backtrace
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.environment_data(job)
|
42
|
+
job_data =
|
43
|
+
JOB_TRACKED_DATA.each_with_object({}) do |data_param, dict|
|
44
|
+
dict.merge(data_param => job.try(data_param))
|
45
|
+
end
|
46
|
+
|
47
|
+
job_class = if job.payload_object.class.name == 'ActiveJob::QueueAdapters::DelayedJobAdapter::JobWrapper'
|
48
|
+
# support for Rails 4.2 ActiveJob
|
49
|
+
job.payload_object.job_data['job_class']
|
50
|
+
elsif job.payload_object.object.is_a?(Class)
|
51
|
+
job.payload_object.object.name
|
52
|
+
else
|
53
|
+
job.payload_object.object.class.name
|
54
|
+
end
|
55
|
+
args_data = (job.payload_object.try(:job_data) || {}).select { |key, _value| ARGS_TRACKED_DATA.include?(key) }
|
56
|
+
|
57
|
+
args_data['job_class'] = job_class || job.payload_object.class.name if args_data['job_class'].nil?
|
58
|
+
|
59
|
+
job_data.merge(args_data)
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.should_track?(attempts)
|
63
|
+
TRACK_AT_RETRY.include?(attempts)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
Delayed::Worker.plugins << ExceptionHunter::Middleware::DelayedJobHunter
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module ExceptionHunter
|
2
|
+
module Middleware
|
3
|
+
class RequestHunter
|
4
|
+
ENVIRONMENT_KEYS =
|
5
|
+
%w[PATH_INFO
|
6
|
+
QUERY_STRING
|
7
|
+
REMOTE_HOST
|
8
|
+
REQUEST_METHOD
|
9
|
+
REQUEST_URI
|
10
|
+
SERVER_PROTOCOL
|
11
|
+
HTTP_HOST
|
12
|
+
CONTENT_TYPE
|
13
|
+
HTTP_USER_AGENT].freeze
|
14
|
+
|
15
|
+
FILTERED_PARAMS = [/password/].freeze
|
16
|
+
|
17
|
+
def initialize(app)
|
18
|
+
@app = app
|
19
|
+
end
|
20
|
+
|
21
|
+
def call(env)
|
22
|
+
@app.call(env)
|
23
|
+
rescue Exception => exception # rubocop:disable Lint/RescueException
|
24
|
+
catch_prey(env, exception)
|
25
|
+
raise exception
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def catch_prey(env, exception)
|
31
|
+
user = user_from_env(env)
|
32
|
+
ErrorCreator.call(
|
33
|
+
tag: ErrorCreator::HTTP_TAG,
|
34
|
+
class_name: exception.class.to_s,
|
35
|
+
message: exception.message,
|
36
|
+
environment_data: environment_data(env),
|
37
|
+
backtrace: exception.backtrace,
|
38
|
+
user: user
|
39
|
+
)
|
40
|
+
end
|
41
|
+
|
42
|
+
def environment_data(env)
|
43
|
+
env
|
44
|
+
.select { |key, _value| ENVIRONMENT_KEYS.include?(key) }
|
45
|
+
.merge(params: filtered_sensitive_params(env))
|
46
|
+
end
|
47
|
+
|
48
|
+
def user_from_env(env)
|
49
|
+
current_user_method = Config.current_user_method
|
50
|
+
controller = env['action_controller.instance']
|
51
|
+
controller.try(current_user_method)
|
52
|
+
end
|
53
|
+
|
54
|
+
def filtered_sensitive_params(env)
|
55
|
+
params = env['action_dispatch.request.parameters']
|
56
|
+
parameter_filter = ::ActiveSupport::ParameterFilter.new(FILTERED_PARAMS)
|
57
|
+
parameter_filter.filter(params || {})
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
module ExceptionHunter
|
64
|
+
class Railtie < Rails::Railtie
|
65
|
+
initializer 'exception_hunter.add_middleware', after: :load_config_initializers do |app|
|
66
|
+
app.config.middleware.insert_after(
|
67
|
+
ActionDispatch::DebugExceptions, ExceptionHunter::Middleware::RequestHunter
|
68
|
+
)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module ExceptionHunter
|
2
|
+
module Middleware
|
3
|
+
# Middleware to report errors
|
4
|
+
# when a Sidekiq worker fails
|
5
|
+
#
|
6
|
+
class SidekiqHunter
|
7
|
+
TRACK_AT_RETRY = [0, 3, 6, 10].freeze
|
8
|
+
JOB_TRACKED_DATA = %w[
|
9
|
+
queue
|
10
|
+
retry_count
|
11
|
+
].freeze
|
12
|
+
ARGS_TRACKED_DATA = %w[
|
13
|
+
job_class
|
14
|
+
job_id
|
15
|
+
arguments
|
16
|
+
enqueued_at
|
17
|
+
].freeze
|
18
|
+
|
19
|
+
def call(_worker, context, _queue)
|
20
|
+
yield
|
21
|
+
rescue Exception => exception # rubocop:disable Lint/RescueException
|
22
|
+
track_exception(exception, context)
|
23
|
+
raise exception
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def track_exception(exception, context)
|
29
|
+
return unless should_track?(context)
|
30
|
+
|
31
|
+
ErrorCreator.call(
|
32
|
+
tag: ErrorCreator::WORKER_TAG,
|
33
|
+
class_name: exception.class.to_s,
|
34
|
+
message: exception.message,
|
35
|
+
environment_data: environment_data(context),
|
36
|
+
backtrace: exception.backtrace
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
def environment_data(context)
|
41
|
+
job_data = context.select { |key, _value| JOB_TRACKED_DATA.include?(key) }
|
42
|
+
args_data = (context['args']&.first || {}).select { |key, _value| ARGS_TRACKED_DATA.include?(key) }
|
43
|
+
|
44
|
+
job_data.merge(args_data)
|
45
|
+
end
|
46
|
+
|
47
|
+
def should_track?(context)
|
48
|
+
TRACK_AT_RETRY.include?(context['retry_count'].to_i)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# As seen in https://github.com/mperham/sidekiq/wiki/Error-Handling
|
55
|
+
Sidekiq.configure_server do |config|
|
56
|
+
config.server_middleware do |chain|
|
57
|
+
chain.add(ExceptionHunter::Middleware::SidekiqHunter)
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module ExceptionHunter
|
2
|
+
module Tracking
|
3
|
+
def track(exception, custom_data: {}, user: nil)
|
4
|
+
ErrorCreator.call(
|
5
|
+
tag: ErrorCreator::MANUAL_TAG,
|
6
|
+
class_name: exception.class.to_s,
|
7
|
+
message: exception.message,
|
8
|
+
backtrace: exception.backtrace,
|
9
|
+
custom_data: custom_data,
|
10
|
+
user: user,
|
11
|
+
environment_data: {}
|
12
|
+
)
|
13
|
+
|
14
|
+
nil
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -3,11 +3,15 @@ module ExceptionHunter
|
|
3
3
|
extend self
|
4
4
|
|
5
5
|
def collect_attributes(user)
|
6
|
+
return unless user
|
7
|
+
|
6
8
|
attributes.reduce({}) do |data, attribute|
|
7
9
|
data.merge(attribute => user.try(attribute))
|
8
10
|
end
|
9
11
|
end
|
10
12
|
|
13
|
+
private
|
14
|
+
|
11
15
|
def attributes
|
12
16
|
Config.user_attributes
|
13
17
|
end
|
@@ -22,7 +22,14 @@ module ExceptionHunter
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def create_admin_user
|
25
|
-
invoke 'devise', [name]
|
25
|
+
invoke 'devise', [name], routes: false
|
26
|
+
end
|
27
|
+
|
28
|
+
def remove_registerable_from_model
|
29
|
+
return if options[:registerable]
|
30
|
+
|
31
|
+
model_file = File.join(destination_root, 'app', 'models', "#{file_path}.rb")
|
32
|
+
gsub_file model_file, /\:registerable([.]*,)?/, ''
|
26
33
|
end
|
27
34
|
end
|
28
35
|
end
|
@@ -15,7 +15,9 @@ module ExceptionHunter
|
|
15
15
|
|
16
16
|
def setup_routes
|
17
17
|
if options[:users]
|
18
|
-
|
18
|
+
gsub_file 'config/routes.rb',
|
19
|
+
"\n devise_for :#{plural_table_name}, skip: :all",
|
20
|
+
"\n ExceptionHunter.routes(self)"
|
19
21
|
else
|
20
22
|
route 'ExceptionHunter.routes(self)'
|
21
23
|
end
|
data/lib/generators/exception_hunter/install/templates/create_exception_hunter_error_groups.rb.erb
CHANGED
@@ -5,10 +5,13 @@ class CreateExceptionHunterErrorGroups < ActiveRecord::Migration[<%= ActiveRecor
|
|
5
5
|
create_table :exception_hunter_error_groups do |t|
|
6
6
|
t.string :error_class_name, null: false
|
7
7
|
t.string :message
|
8
|
+
t.integer :status, default: 0
|
9
|
+
t.text :tags, array: true, default: []
|
8
10
|
|
9
11
|
t.timestamps
|
10
12
|
|
11
13
|
t.index :message, opclass: :gin_trgm_ops, using: :gin
|
14
|
+
t.index :status
|
12
15
|
end
|
13
16
|
end
|
14
17
|
end
|
@@ -1,4 +1,19 @@
|
|
1
1
|
ExceptionHunter.setup do |config|
|
2
|
+
# == Enabling
|
3
|
+
#
|
4
|
+
# This flag allows disabling error tracking, it's set to track in
|
5
|
+
# any environment but development or test by default
|
6
|
+
#
|
7
|
+
config.enabled = !(Rails.env.development? || Rails.env.test?)
|
8
|
+
|
9
|
+
# == Dashboard User
|
10
|
+
# Exception Hunter allows you to restrict users who can see the dashboard
|
11
|
+
# to the ones included in the database. You can change the table name in
|
12
|
+
# case you are not satisfied with the default one. You can also remove the
|
13
|
+
# configuration if you wish to have no access restrictions for the dashboard.
|
14
|
+
#
|
15
|
+
<%= @use_authentication_method ? "config.admin_user_class = '#{name}'" : "# config.admin_user_class = '#{name}'" %>
|
16
|
+
|
2
17
|
# == Current User
|
3
18
|
#
|
4
19
|
# Exception Hunter will include the user as part of the environment
|
@@ -15,4 +30,12 @@ ExceptionHunter.setup do |config|
|
|
15
30
|
# as part of the user information that is kept from the request.
|
16
31
|
#
|
17
32
|
config.user_attributes = [:id, :email]
|
33
|
+
|
34
|
+
# == Stale errors
|
35
|
+
#
|
36
|
+
# You can configure how long it takes for errors to go stale. This is
|
37
|
+
# taken into account when purging old error messages but nothing will
|
38
|
+
# happen automatically.
|
39
|
+
#
|
40
|
+
# config.errors_stale_time = 45.days
|
18
41
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: exception_hunter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bruno Vezoli
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2020-
|
12
|
+
date: 2020-09-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: pagy
|
@@ -17,14 +17,14 @@ dependencies:
|
|
17
17
|
requirements:
|
18
18
|
- - "~>"
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: '3
|
20
|
+
version: '3'
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
25
|
- - "~>"
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version: '3
|
27
|
+
version: '3'
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: brakeman
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
@@ -115,14 +115,14 @@ dependencies:
|
|
115
115
|
requirements:
|
116
116
|
- - "~>"
|
117
117
|
- !ruby/object:Gem::Version
|
118
|
-
version: 0.
|
118
|
+
version: 0.17.1
|
119
119
|
type: :development
|
120
120
|
prerelease: false
|
121
121
|
version_requirements: !ruby/object:Gem::Requirement
|
122
122
|
requirements:
|
123
123
|
- - "~>"
|
124
124
|
- !ruby/object:Gem::Version
|
125
|
-
version: 0.
|
125
|
+
version: 0.17.1
|
126
126
|
description:
|
127
127
|
email:
|
128
128
|
- bruno.vezoli@rootstrap.com
|
@@ -139,31 +139,46 @@ files:
|
|
139
139
|
- app/assets/stylesheets/exception_hunter/base.css
|
140
140
|
- app/assets/stylesheets/exception_hunter/errors.css
|
141
141
|
- app/assets/stylesheets/exception_hunter/navigation.css
|
142
|
+
- app/assets/stylesheets/exception_hunter/sessions.css
|
143
|
+
- app/controllers/concerns/exception_hunter/authorization.rb
|
142
144
|
- app/controllers/exception_hunter/application_controller.rb
|
143
145
|
- app/controllers/exception_hunter/errors_controller.rb
|
146
|
+
- app/controllers/exception_hunter/resolved_errors_controller.rb
|
144
147
|
- app/helpers/exception_hunter/application_helper.rb
|
148
|
+
- app/helpers/exception_hunter/errors_helper.rb
|
149
|
+
- app/helpers/exception_hunter/sessions_helper.rb
|
145
150
|
- app/jobs/exception_hunter/application_job.rb
|
146
151
|
- app/mailers/exception_hunter/application_mailer.rb
|
147
152
|
- app/models/exception_hunter/application_record.rb
|
148
153
|
- app/models/exception_hunter/error.rb
|
149
154
|
- app/models/exception_hunter/error_group.rb
|
155
|
+
- app/presenters/exception_hunter/dashboard_presenter.rb
|
156
|
+
- app/presenters/exception_hunter/error_group_presenter.rb
|
150
157
|
- app/presenters/exception_hunter/error_presenter.rb
|
151
|
-
- app/
|
158
|
+
- app/views/exception_hunter/devise/sessions/new.html.erb
|
152
159
|
- app/views/exception_hunter/errors/_error_backtrace.erb
|
160
|
+
- app/views/exception_hunter/errors/_error_row.erb
|
153
161
|
- app/views/exception_hunter/errors/_error_summary.erb
|
154
162
|
- app/views/exception_hunter/errors/_error_user_data.erb
|
163
|
+
- app/views/exception_hunter/errors/_errors_table.erb
|
164
|
+
- app/views/exception_hunter/errors/_last_7_days_errors_table.erb
|
155
165
|
- app/views/exception_hunter/errors/index.html.erb
|
156
166
|
- app/views/exception_hunter/errors/pagy/_pagy_nav.html.erb
|
157
167
|
- app/views/exception_hunter/errors/show.html.erb
|
158
168
|
- app/views/layouts/exception_hunter/application.html.erb
|
159
|
-
-
|
169
|
+
- app/views/layouts/exception_hunter/exception_hunter_logged_out.html.erb
|
160
170
|
- config/rails_best_practices.yml
|
161
171
|
- config/routes.rb
|
162
172
|
- lib/exception_hunter.rb
|
163
173
|
- lib/exception_hunter/config.rb
|
174
|
+
- lib/exception_hunter/devise.rb
|
164
175
|
- lib/exception_hunter/engine.rb
|
165
|
-
- lib/exception_hunter/
|
166
|
-
- lib/exception_hunter/
|
176
|
+
- lib/exception_hunter/error_creator.rb
|
177
|
+
- lib/exception_hunter/error_reaper.rb
|
178
|
+
- lib/exception_hunter/middleware/delayed_job_hunter.rb
|
179
|
+
- lib/exception_hunter/middleware/request_hunter.rb
|
180
|
+
- lib/exception_hunter/middleware/sidekiq_hunter.rb
|
181
|
+
- lib/exception_hunter/tracking.rb
|
167
182
|
- lib/exception_hunter/user_attributes_collector.rb
|
168
183
|
- lib/exception_hunter/version.rb
|
169
184
|
- lib/generators/exception_hunter/create_users/create_users_generator.rb
|