activeerror 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 7152e2ef6d0ce997ab2c1ac6ad20301641bc3888da16d14d8ba447f0f25bbe42
4
+ data.tar.gz: c75638bb627a0bc6250e3eb7fd2c0041dda4eb7b1ac6849de0d2bda07cd7663d
5
+ SHA512:
6
+ metadata.gz: 2576054be5ff1b83af55777b9135a991e6fe05a845c1197d55aad43b79676fb830a09712be37c0d7591f1eb7f5e36b09af7ad8c71cf3a129f32a9d985dd3fb5d
7
+ data.tar.gz: 81ff00bc1f0e4e0fbe9230ec37e0fb72b1bc960375f9c64c9c6348fff2ec6ca2d8f98b237dec00b9e02fadbd4a7eee9b3427d2aea486f5c747ed06b479df0f9c
data/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2019 Nick Pezza
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,71 @@
1
+ # ActiveError
2
+
3
+ One of the fundemental tools needed to take your Rails app to production is a
4
+ way to track errors that are triggered. Unfortunately, theres no free, easy,
5
+ open source way to track them for small or medium apps. Honeybadger and Sentry are great,
6
+ but they are only free for a single user and are closed source. With Sentry
7
+ looking at using your data as training
8
+ data([link](https://blog.sentry.io/ai-privacy-and-terms-of-service-updates/?original_referrer=https%3A%2F%2Fsentry.io%2F))
9
+ there should be an easy open source alternative where you control the data.
10
+
11
+ ActiveError hooks into the [error reporting
12
+ api](https://guides.rubyonrails.org/error_reporting.html) baked directly into
13
+ Rails. These third party error loggers also try to make their own fancy
14
+ backtrace and debugging view. But the one Rails developers are most comfortable
15
+ with is the one baked into Rails that we use everyday in development. So with
16
+ ActiveError, when an error gets raised it's captured and stored in the
17
+ database (we attempt to group the same error together as Instances to reduce
18
+ noise) and then we recreate the error and display it using the built in debug
19
+ view from Rails. Once you've resolved the error you can click "Resolve" with
20
+ will destroy the record.
21
+
22
+ ![screenshot 1](https://github.com/npezza93/active_error/blob/main/.github/screenshot1.png)
23
+ ![screenshot 2](https://github.com/npezza93/active_error/blob/main/.github/screenshot2.png)
24
+
25
+ ## Installation
26
+ Add this line to your application's Gemfile:
27
+
28
+ ```ruby
29
+ gem "activeerror"
30
+ ```
31
+
32
+ And then execute:
33
+ ```bash
34
+ $ bundle
35
+ ```
36
+
37
+ Or install it yourself as:
38
+ ```bash
39
+ $ gem install activeerror
40
+ ```
41
+
42
+ And then install migrations:
43
+ ```bash
44
+ bin/rails active_error:install
45
+ bin/rails rails db:migrate
46
+ ```
47
+
48
+ This also mounts a route n your routes file to view the errors at `/errors`.
49
+
50
+ ## Development
51
+
52
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run
53
+ `rails test` to run the unit tests.
54
+
55
+ To install this gem onto your local machine, run `bundle exec rake install`. To
56
+ release a new version, execute `bin/publish (major|minor|patch)` which will
57
+ update the version number in `version.rb`, create a git tag for the version,
58
+ push git commits and tags, and push the `.gem` file to GitHub.
59
+
60
+ ## Contributing
61
+
62
+ Bug reports and pull requests are welcome on
63
+ [GitHub](https://github.com/npezza93/active_error). This project is intended to
64
+ be a safe, welcoming space for collaboration, and contributors are expected to
65
+ adhere to the [Contributor Covenant](http://contributor-covenant.org) code of
66
+ conduct.
67
+
68
+ ## License
69
+
70
+ The gem is available as open source under the terms of the
71
+ [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ begin
4
+ require "bundler/setup"
5
+ rescue LoadError
6
+ puts "You must `gem install bundler` and `bundle install` to run rake tasks"
7
+ end
8
+
9
+ require "rdoc/task"
10
+
11
+ RDoc::Task.new(:rdoc) do |rdoc|
12
+ rdoc.rdoc_dir = "rdoc"
13
+ rdoc.title = "ActiveError"
14
+ rdoc.options << "--line-numbers"
15
+ rdoc.rdoc_files.include("README.md")
16
+ rdoc.rdoc_files.include("lib/**/*.rb")
17
+ end
18
+
19
+ APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
20
+ load "rails/tasks/engine.rake"
21
+
22
+ load "rails/tasks/statistics.rake"
23
+
24
+ require "bundler/gem_tasks"
25
+
26
+ require "rake/testtask"
27
+
28
+ Rake::TestTask.new(:test) do |t|
29
+ t.libs << "test"
30
+ t.pattern = "test/**/*_test.rb"
31
+ t.verbose = false
32
+ end
33
+
34
+ task default: :test
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveError
4
+ class ApplicationController < ActionController::Base
5
+ protect_from_forgery with: :exception
6
+ end
7
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveError
4
+ module Faults
5
+ class InstancesController < ApplicationController
6
+ def show
7
+ render html: Renderer.new(instance:).body
8
+ end
9
+
10
+ private
11
+
12
+ def instance
13
+ Instance.find_by(fault_id: params[:fault_id], id: params[:id])
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveError
4
+ class FaultsController < ApplicationController
5
+ before_action :set_fault, only: %i(show destroy)
6
+
7
+ def index
8
+ @faults = Fault.top_level
9
+ end
10
+
11
+ def show
12
+ end
13
+
14
+ def destroy
15
+ @fault.destroy
16
+
17
+ redirect_to faults_url, notice: "Exception was resolved"
18
+ end
19
+
20
+ private
21
+
22
+ def set_fault
23
+ @fault = Fault.find(params[:id])
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveError
4
+ class ApplicationRecord < ActiveRecord::Base
5
+ self.abstract_class = true
6
+ end
7
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveError
4
+ class Fault < ApplicationRecord
5
+ has_one :parent_cause, class_name: "ActiveError::Fault",
6
+ foreign_key: :cause_id, inverse_of: :cause,
7
+ dependent: :restrict_with_error
8
+ belongs_to :cause, optional: true, class_name: "ActiveError::Fault",
9
+ dependent: :destroy
10
+ has_many :instances, dependent: :destroy
11
+
12
+ store :options, accessors: [:template], coder: YAML,
13
+ yaml: { unsafe_load: true }
14
+
15
+ serialize :backtrace, type: Array, coder: YAML
16
+ serialize :backtrace_locations, type: Array, coder: YAML,
17
+ yaml: { unsafe_load: true }
18
+ serialize :blamed_files, type: Array, coder: YAML
19
+
20
+ scope :top_level, lambda {
21
+ left_joins(:parent_cause).where(
22
+ parent_causes_active_error_faults: { id: nil }
23
+ )
24
+ }
25
+
26
+ def exception
27
+ ExceptionMock.make(fault: self)
28
+ end
29
+
30
+ def title
31
+ "#{klass}#{controller_display}#{action_display}"
32
+ end
33
+
34
+ def occurrences
35
+ "#{instances_count} #{'instance'.pluralize(instances_count)}"
36
+ end
37
+
38
+ def template
39
+ Marshal.load(super) unless super.nil? # rubocop:disable Security/MarshalLoad
40
+ end
41
+
42
+ def template=(new_template)
43
+ super(Marshal.dump(new_template))
44
+ end
45
+
46
+ private
47
+
48
+ def controller_display
49
+ return unless controller?
50
+
51
+ " in #{controller.camelize}Controller"
52
+ end
53
+
54
+ def action_display
55
+ return unless action? && controller?
56
+
57
+ "##{action}"
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "useragent"
4
+
5
+ module ActiveError
6
+ class Instance < ApplicationRecord
7
+ belongs_to :fault, counter_cache: true
8
+
9
+ serialize :parameters, coder: JSON
10
+ serialize :headers, coder: JSON
11
+
12
+ delegate :browser, :platform, :version, to: :user_agent
13
+
14
+ def user_agent_display
15
+ "#{platform} #{browser} #{version}"
16
+ end
17
+
18
+ def request
19
+ @request ||= ActionDispatch::Request.new(request_env)
20
+ end
21
+
22
+ private
23
+
24
+ def user_agent
25
+ @user_agent ||= UserAgent.parse(headers["HTTP_USER_AGENT"])
26
+ end
27
+
28
+ def request_env
29
+ ENV.to_h.merge(headers).merge(
30
+ "action_dispatch.request.parameters" => parameters,
31
+ )
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,18 @@
1
+ <header>
2
+ <h1>Errors</h1>
3
+ <p id="notice"><%= notice %><p>
4
+ </header>
5
+
6
+ <table>
7
+ <tbody>
8
+ <% @faults.each do |fault| %>
9
+ <tr>
10
+ <td>#<%= fault.id %></td>
11
+ <td><%= link_to fault.title, fault %></td>
12
+ <td class="w-15"><%= time_ago_in_words(fault.created_at).capitalize %> ago</td>
13
+ <td class="w-15"><%= fault.occurrences %></td>
14
+ <td class="w-5"><%= button_to 'Resolve', fault, method: :delete, form: { onSubmit: "return confirm('Are you sure?')" }, class: "button-as-link" %></td>
15
+ </tr>
16
+ <% end %>
17
+ </tbody>
18
+ </table>
@@ -0,0 +1,17 @@
1
+ <header>
2
+ <h1>Instances of <%= @fault.title %> (Fault #<%= @fault.id %>)</h1>
3
+ <p id="notice"><%= notice %><p>
4
+ </header>
5
+
6
+ <table>
7
+ <tbody>
8
+ <% @fault.instances.each do |instance| %>
9
+ <tr>
10
+ <td>#<%= instance.id %></td>
11
+ <td><%= link_to instance.url, fault_instance_path(@fault, instance) %></td>
12
+ <td class="w-15"><%= instance.user_agent_display %></td>
13
+ <td class="w-15"><%= time_ago_in_words(instance.created_at).capitalize %> ago</td>
14
+ </tr>
15
+ <% end %>
16
+ </tbody>
17
+ </table>
@@ -0,0 +1,98 @@
1
+ <!DOCTYPE html>
2
+ <html class="active_error">
3
+ <head>
4
+ <title>Active error</title>
5
+ <%= csrf_meta_tags %>
6
+ <%= csp_meta_tag %>
7
+
8
+ <style>
9
+ .active_error body {
10
+ background-color: #FAFAFA;
11
+ color: #333;
12
+ color-scheme: light dark;
13
+ supported-color-schemes: light dark;
14
+ margin: 0px;
15
+ }
16
+
17
+ @media (prefers-color-scheme: dark) {
18
+ .active_error body {
19
+ background-color: #222;
20
+ color: #ECECEC;
21
+ }
22
+ }
23
+
24
+ .active_error body, .active_error p, .active_error ol, .active_error ul, .active_error td {
25
+ font-family: helvetica, verdana, arial, sans-serif;
26
+ font-size: 13px;
27
+ line-height: 18px;
28
+ }
29
+
30
+ .active_error .button-as-link {
31
+ border: none;
32
+ text-decoration: underline;
33
+ cursor: pointer;
34
+ background: none;
35
+ font-size: 15px;
36
+ margin: 0;
37
+ padding: 0;
38
+ line-height: 18px;
39
+ }
40
+
41
+ .active_error a, .active_error .button-as-link { color: #980905; }
42
+ .active_error a:visited, .active_error .button-as-link:visited { color: #666; }
43
+ .active_error a.trace-frames {
44
+ color: #666;
45
+ overflow-wrap: break-word;
46
+ }
47
+ .active_error a:hover, .active_error .button-as-link:hover, .active_error a.trace-frames.selected { color: #C00; }
48
+ .active_error a.summary:hover { color: #FFF; }
49
+
50
+ .active_error th {
51
+ padding-bottom: 5px;
52
+ }
53
+
54
+ .active_error td {
55
+ padding: 0 5px 7px;
56
+ }
57
+
58
+ .active_error #notice {
59
+ color: #d3f0b7;
60
+ }
61
+
62
+ .active_error header {
63
+ color: #f0f0f0;
64
+ background: #C00;
65
+ padding: 0.5em 1.5em;
66
+ display: flex;
67
+ flex-direction: row;
68
+ margin-bottom: 0.83em;
69
+ }
70
+
71
+ .active_error h1 {
72
+ flex: 1;
73
+ overflow-wrap: break-word;
74
+ margin: 0.2em 0;
75
+ line-height: 1.1em;
76
+ font-size: 2em;
77
+ }
78
+
79
+ .active_error table {
80
+ padding: 0 1.5em;
81
+ width: 100%;
82
+ }
83
+
84
+ .active_error table tr td:first-of-type {
85
+ padding-left: 0;
86
+ }
87
+
88
+ .active_error .w-5 {
89
+ width: 5%;
90
+ }
91
+
92
+ .active_error .w-15 {
93
+ width: 15%;
94
+ }
95
+ </style>
96
+ </head>
97
+ <body><%= yield %></body>
98
+ </html>
data/config/routes.rb ADDED
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ ActiveError::Engine.routes.draw do
4
+ resources :faults, only: %i(index show destroy) do
5
+ scope module: :faults do
6
+ resources :instances, only: :show
7
+ end
8
+ end
9
+
10
+ root "faults#index"
11
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateActiveErrorFaults < ActiveRecord::Migration[7.1]
4
+ def change
5
+ create_table :active_error_faults do |t|
6
+ t.belongs_to :cause
7
+ t.text :backtrace
8
+ t.text :backtrace_locations
9
+ t.string :klass
10
+ t.text :message
11
+ t.string :controller
12
+ t.string :action
13
+ t.integer :instances_count
14
+ t.text :blamed_files
15
+ t.text :options
16
+ t.index %i(klass backtrace message)
17
+
18
+ t.timestamps
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateActiveErrorInstances < ActiveRecord::Migration[7.1]
4
+ def change
5
+ create_table :active_error_instances do |t|
6
+ t.belongs_to :fault
7
+ t.string :url
8
+ t.text :headers
9
+ t.text :parameters
10
+
11
+ t.timestamps
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveError
4
+ BacktraceLocation = Struct.new(:absolute_path, :base_label, :to_s, :label, # rubocop:disable Lint/StructNewOverride
5
+ :lineno, :path) do
6
+ def inspect = to_s
7
+
8
+ def spot(exception)
9
+ end
10
+ end
11
+
12
+ class Captor
13
+ def initialize(exception:, request:, capture_instance: true)
14
+ @exception = exception
15
+ @request = request
16
+ @capture_instance = capture_instance
17
+ end
18
+
19
+ def capture
20
+ create_instance if capture_instance?
21
+ fault
22
+ end
23
+
24
+ private
25
+
26
+ attr_reader :exception, :request, :capture_instance
27
+
28
+ delegate :parameters, to: :request
29
+
30
+ def fault
31
+ @fault ||= Fault.default_scoped.find_or_create_by(fault_attrs) do |fault|
32
+ fault.message = exception.message
33
+ fault.cause = cause
34
+ fault.backtrace_locations = backtrace_locations
35
+ fault.template = template if template?
36
+ end
37
+ end
38
+
39
+ def fault_attrs
40
+ { backtrace: exception.backtrace, klass: exception.class.to_s,
41
+ controller: parameters[:controller], action: parameters[:action] }
42
+ end
43
+
44
+ def template?
45
+ exception.class.is_a?(ActionView::Template::Error)
46
+ end
47
+
48
+ def template
49
+ exception.instance_variable_get(:@template)
50
+ end
51
+
52
+ def cause
53
+ return if exception.cause.blank?
54
+
55
+ self.class.new(exception: exception.cause, request:,
56
+ capture_instance: false).capture
57
+ end
58
+
59
+ def backtrace_locations
60
+ exception.backtrace_locations&.map do |location|
61
+ BacktraceLocation.new(location.absolute_path, location.base_label,
62
+ location.to_s, location.label, location.lineno,
63
+ location.path)
64
+ end
65
+ end
66
+
67
+ def capture_instance?
68
+ capture_instance
69
+ end
70
+
71
+ def create_instance
72
+ headers = request.env.
73
+ slice(*ActionDispatch::Request::ENV_METHODS, "HTTP_USER_AGENT")
74
+
75
+ fault.instances.create(headers:, parameters: request.filtered_parameters,
76
+ url: request.url)
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveError
4
+ class ErrorSubscriber
5
+ def report(exception, context:, **_opts)
6
+ return if Rails.env.local?
7
+
8
+ Captor.new(exception:, request: context[:active_error_request]).capture
9
+ end
10
+ end
11
+
12
+ class Engine < ::Rails::Engine
13
+ isolate_namespace ActiveError
14
+
15
+ initializer "active_error.middleware" do |_app|
16
+ ActionController::Base.before_action do
17
+ Rails.error.set_context(active_error_request: request)
18
+ end
19
+ Rails.error.subscribe(::ActiveError::ErrorSubscriber.new)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ # require "active_support/dependencies"
4
+
5
+ module ActiveError
6
+ module ExceptionMock
7
+ class Default < StandardError
8
+ # include ActiveSupport::Dependencies::Blamable
9
+
10
+ def initialize(fault:)
11
+ @klass = fault.klass
12
+ @backtrace = fault.backtrace
13
+ @backtrace_locations = fault.backtrace_locations
14
+ @message = fault.message
15
+ # @blamed_files = fault.blamed_files
16
+ @cause = ExceptionMock.make(fault: fault.cause)
17
+ end
18
+
19
+ def class
20
+ klass.constantize
21
+ end
22
+
23
+ attr_reader :backtrace, :backtrace_locations, :message, :cause,
24
+ :line_number
25
+
26
+ private
27
+
28
+ attr_reader :klass
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "action_view/template/error"
4
+
5
+ module ActiveError
6
+ module ExceptionMock
7
+ class TemplateError < ActionView::Template::Error
8
+ def initialize(fault:)
9
+ @klass = fault.klass
10
+ set_backtrace(fault.backtrace)
11
+ @message = fault.message
12
+ @blamed_files = fault.blamed_files
13
+ @template = fault.template
14
+ @cause = ExceptionMock.make(fault: fault.cause)
15
+ end
16
+
17
+ def class
18
+ klass.constantize
19
+ end
20
+
21
+ attr_reader :message
22
+
23
+ private
24
+
25
+ attr_reader :klass
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveError
4
+ module ExceptionMock
5
+ def self.make(fault:)
6
+ case fault&.klass
7
+ when "ActionView::Template::Error" then TemplateError.new(fault:)
8
+ when nil then nil
9
+ else
10
+ Default.new(fault:)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveError
4
+ class Renderer
5
+ def initialize(instance:)
6
+ @instance = instance
7
+ @exception = instance.fault.exception
8
+ end
9
+
10
+ def body
11
+ @body ||= template.render(template: file, layout: "rescues/layout")
12
+ end
13
+
14
+ private
15
+
16
+ attr_reader :exception, :instance
17
+
18
+ delegate :trace_to_show, :source_to_show_id, :source_extracts,
19
+ :traces, to: :wrapper
20
+
21
+ def backtrace_cleaner
22
+ Rails.backtrace_cleaner
23
+ end
24
+
25
+ def wrapper
26
+ @wrapper ||=
27
+ ActionDispatch::ExceptionWrapper.new(backtrace_cleaner, exception)
28
+ end
29
+
30
+ def file
31
+ "rescues/#{wrapper.rescue_template}"
32
+ end
33
+
34
+ def template
35
+ ActionDispatch::DebugView.new(
36
+ request: instance.request, exception_wrapper: wrapper,
37
+ exception: wrapper.exception, traces:,
38
+ show_source_idx: source_to_show_id, trace_to_show:, source_extracts:
39
+ )
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveError
4
+ VERSION = Gem::Version.new("1.0.0")
5
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_error/exception_mock/default"
4
+ require "active_error/exception_mock/template_error"
5
+ require "active_error/exception_mock"
6
+ require "active_error/captor"
7
+ require "active_error/renderer"
8
+ require "active_error/engine"
9
+ require "active_error/version"
10
+
11
+ module ActiveError
12
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_error"
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ActiveError::InstallGenerator < Rails::Generators::Base
4
+ def add_route
5
+ route "mount ActiveError::Engine => \"/errors\""
6
+ end
7
+
8
+ def create_migrations
9
+ rails_command "active_error:install:migrations", inline: true
10
+ end
11
+ end
metadata ADDED
@@ -0,0 +1,97 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: activeerror
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Nick Pezza
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2024-01-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '7.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '7.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: useragent
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description:
42
+ email:
43
+ - pezza@hey.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - LICENSE.md
49
+ - README.md
50
+ - Rakefile
51
+ - app/controllers/active_error/application_controller.rb
52
+ - app/controllers/active_error/faults/instances_controller.rb
53
+ - app/controllers/active_error/faults_controller.rb
54
+ - app/models/active_error/application_record.rb
55
+ - app/models/active_error/fault.rb
56
+ - app/models/active_error/instance.rb
57
+ - app/views/active_error/faults/index.html.erb
58
+ - app/views/active_error/faults/show.html.erb
59
+ - app/views/layouts/active_error/application.html.erb
60
+ - config/routes.rb
61
+ - db/migrate/20200727220359_create_active_error_faults.rb
62
+ - db/migrate/20200727225318_create_active_error_instances.rb
63
+ - lib/active_error.rb
64
+ - lib/active_error/captor.rb
65
+ - lib/active_error/engine.rb
66
+ - lib/active_error/exception_mock.rb
67
+ - lib/active_error/exception_mock/default.rb
68
+ - lib/active_error/exception_mock/template_error.rb
69
+ - lib/active_error/renderer.rb
70
+ - lib/active_error/version.rb
71
+ - lib/activeerror.rb
72
+ - lib/generators/active_error/install/install_generator.rb
73
+ homepage: https://github.com/npezza93/active_error
74
+ licenses:
75
+ - MIT
76
+ metadata:
77
+ rubygems_mfa_required: 'true'
78
+ post_install_message:
79
+ rdoc_options: []
80
+ require_paths:
81
+ - lib
82
+ required_ruby_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: 3.1.0
87
+ required_rubygems_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ requirements: []
93
+ rubygems_version: 3.5.3
94
+ signing_key:
95
+ specification_version: 4
96
+ summary: Rails exception logger
97
+ test_files: []