activeerror 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []