error_ready 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +30 -0
  4. data/Rakefile +8 -0
  5. data/app/assets/config/error_ready_manifest.js +1 -0
  6. data/app/assets/images/error_ready/showcase.png +0 -0
  7. data/app/assets/stylesheets/error_ready/application.css +15 -0
  8. data/app/controllers/error_ready/application_controller.rb +4 -0
  9. data/app/controllers/error_ready/problems_controller.rb +26 -0
  10. data/app/helpers/error_ready/application_helper.rb +4 -0
  11. data/app/helpers/error_ready/problems_helper.rb +4 -0
  12. data/app/jobs/error_ready/application_job.rb +4 -0
  13. data/app/mailers/error_ready/application_mailer.rb +6 -0
  14. data/app/models/error_ready/application_record.rb +5 -0
  15. data/app/models/error_ready/notice.rb +5 -0
  16. data/app/models/error_ready/problem.rb +15 -0
  17. data/app/views/error_ready/problems/_problem.html.erb +33 -0
  18. data/app/views/error_ready/problems/index.html.erb +10 -0
  19. data/app/views/error_ready/problems/show.html.erb +28 -0
  20. data/app/views/layouts/error_ready/application.html.erb +16 -0
  21. data/config/routes.rb +3 -0
  22. data/db/migrate/20221005120809_create_error_ready_problems.rb +16 -0
  23. data/db/migrate/20221005135120_create_error_ready_notices.rb +11 -0
  24. data/lib/error_ready/engine.rb +11 -0
  25. data/lib/error_ready/formatter.rb +23 -0
  26. data/lib/error_ready/notifiers/database.rb +33 -0
  27. data/lib/error_ready/rack_middleware.rb +19 -0
  28. data/lib/error_ready/subscriber.rb +16 -0
  29. data/lib/error_ready/version.rb +3 -0
  30. data/lib/error_ready.rb +11 -0
  31. data/lib/tasks/error_ready_tasks.rake +4 -0
  32. metadata +91 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 54c1d662e9dc0e27d2c488f68e32a26bba5182884dcb6937bcf470bc61db8662
4
+ data.tar.gz: 7a72b704734f9ae5644442df7d589571bff00488a705c0261d0daaf45964c2de
5
+ SHA512:
6
+ metadata.gz: 2fd231f46958d06ec1aef6421e52113b6172ae3470e9f93fd3e2134224be7a3c7ddadd102a30c95cd928ef85e4a96c81d7ea476fa3c31a3a35c12f2b1c739b8d
7
+ data.tar.gz: bcaa37cfcbf86880a73fac9eb7de3b0795f867520eb56137b14bf2e9af1bc2606c8f8a638c4ccf5af2b0622c33e655ba9bf910f72339f2f336aa5bbcd7de98e8
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2022 Moses Gathuku
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,30 @@
1
+ # ErrorReady
2
+ A plugin thats records errors and store them in the database you already have.
3
+
4
+ ![Showcase image](app/assets/images/error_ready/showcase.png)
5
+
6
+ ## Usage
7
+ coming soon
8
+
9
+ ## Installation
10
+ Add this line to your application's Gemfile:
11
+
12
+ ```ruby
13
+ gem "error_ready"
14
+ ```
15
+
16
+ And then execute:
17
+ ```bash
18
+ $ bundle
19
+ ```
20
+
21
+ Or install it yourself as:
22
+ ```bash
23
+ $ gem install error_ready
24
+ ```
25
+
26
+ ## Contributing
27
+ Contribution directions go here.
28
+
29
+ ## License
30
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require "bundler/setup"
2
+
3
+ APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
4
+ load "rails/tasks/engine.rake"
5
+
6
+ load "rails/tasks/statistics.rake"
7
+
8
+ require "bundler/gem_tasks"
@@ -0,0 +1 @@
1
+ //= link_directory ../stylesheets/error_ready .css
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,4 @@
1
+ module ErrorReady
2
+ class ApplicationController < ActionController::Base
3
+ end
4
+ end
@@ -0,0 +1,26 @@
1
+ module ErrorReady
2
+ class ProblemsController < ApplicationController
3
+ before_action :set_problem, only: %i[ show destroy ]
4
+
5
+ # GET /problems
6
+ def index
7
+ @problems = Problem.latest_first
8
+ end
9
+
10
+ # GET /problems/1
11
+ def show
12
+ end
13
+
14
+ # DELETE /problems/1
15
+ def destroy
16
+ @problem.destroy
17
+ redirect_to problems_url, notice: "Problem was successfully destroyed."
18
+ end
19
+
20
+ private
21
+ # Use callbacks to share common setup or constraints between actions.
22
+ def set_problem
23
+ @problem = Problem.find(params[:id])
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,4 @@
1
+ module ErrorReady
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module ErrorReady
2
+ module ProblemsHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module ErrorReady
2
+ class ApplicationJob < ActiveJob::Base
3
+ end
4
+ end
@@ -0,0 +1,6 @@
1
+ module ErrorReady
2
+ class ApplicationMailer < ActionMailer::Base
3
+ default from: "from@example.com"
4
+ layout "mailer"
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ module ErrorReady
2
+ class ApplicationRecord < ActiveRecord::Base
3
+ self.abstract_class = true
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module ErrorReady
2
+ class Notice < ApplicationRecord
3
+ belongs_to :problem, foreign_key: "error_ready_problem_id"
4
+ end
5
+ end
@@ -0,0 +1,15 @@
1
+ module ErrorReady
2
+ class Problem < ApplicationRecord
3
+
4
+ has_many :notices, foreign_key: "error_ready_problem_id"
5
+
6
+ attribute :first_notice_at, :datetime, default: Time.current
7
+ attribute :last_notice_at, :datetime, default: Time.current
8
+ attribute :notices_count, :integer, default: 0
9
+
10
+ scope :resolved, -> { where.not(resolved_at: nil) }
11
+ scope :unresolved, -> { where(resolved_at: nil) }
12
+ scope :latest_first, -> { order(last_notice_at: :desc)}
13
+
14
+ end
15
+ end
@@ -0,0 +1,33 @@
1
+ <li>
2
+ <%= link_to problem_path(problem), class:"block hover:bg-gray-50" do %>
3
+ <div class="flex items-center py-4 ">
4
+ <div class="min-w-0 flex-1 sm:flex sm:items-center sm:justify-between">
5
+ <div class="truncate">
6
+ <div class="flex text-sm">
7
+ <p class="truncate font-medium text-indigo-600"><%= problem.err_class %></p>
8
+ <p class="ml-1 flex-shrink-0 font-normal text-gray-500">in <%= problem.environment %></p>
9
+ </div>
10
+ <div class="mt-2">
11
+ <div class="flex items-center text-sm text-gray-500">
12
+ <!-- Heroicon name: mini/calendar -->
13
+ <svg class="mr-1.5 h-5 w-5 flex-shrink-0 text-gray-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
14
+ <path fill-rule="evenodd" d="M5.75 2a.75.75 0 01.75.75V4h7V2.75a.75.75 0 011.5 0V4h.25A2.75 2.75 0 0118 6.75v8.5A2.75 2.75 0 0115.25 18H4.75A2.75 2.75 0 012 15.25v-8.5A2.75 2.75 0 014.75 4H5V2.75A.75.75 0 015.75 2zm-1 5.5c-.69 0-1.25.56-1.25 1.25v6.5c0 .69.56 1.25 1.25 1.25h10.5c.69 0 1.25-.56 1.25-1.25v-6.5c0-.69-.56-1.25-1.25-1.25H4.75z" clip-rule="evenodd" />
15
+ </svg>
16
+ <p>
17
+ Last notice on
18
+ <time datetime="2020-01-07"><%= problem.last_notice_at %></time>
19
+ </p>
20
+ </div>
21
+ <div class="mt-2">
22
+ <span class="text-gray-700 text-sm truncate"><%= problem.message %></span>
23
+ </div>
24
+ </div>
25
+ </div>
26
+
27
+ </div>
28
+ <div class="ml-5 flex-shrink-0 text-green-600">
29
+ <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
30
+ </div>
31
+ </div>
32
+ <% end %>
33
+ </li>
@@ -0,0 +1,10 @@
1
+ <p style="color: green"><%= notice %></p>
2
+ <div class="mt-3">
3
+ <h1 class="font-bold text-gray-700 leading-tight text-2xl">Problems</h1>
4
+
5
+ <div id="problems" class="mt-3">
6
+ <ul class="divide-y">
7
+ <%= render @problems %>
8
+ </ul>
9
+ </div>
10
+ </div>
@@ -0,0 +1,28 @@
1
+
2
+ <div class="mt-6">
3
+ <div class="flex justify-between items-center">
4
+ <span class="font-bold text-gray-700 text-xl"><%= @problem.err_class %></span>
5
+ <span class="bg-gray-200 rounded-md p-2 text-gray-800">Resolve</span>
6
+ </div>
7
+
8
+ <div>
9
+ <span class="block font-semibold">message:</span>
10
+ <%= @problem.message %>
11
+ </div>
12
+
13
+ <div class="mt-3">
14
+ <span class="font-semibold">Context:</span>
15
+ <% @problem.notices.first.context.each do |k,v| %>
16
+ <span class="block"><%= k.gsub('_', ' ').capitalize %>: <%= v %></span>
17
+ <% end %>
18
+ </div>
19
+
20
+ <div class="mt-3">
21
+ <span class="font-semibold">Backtrace:</span>
22
+ <div class="text-sm bg-gray-200 p-2">
23
+ <% @problem.notices.first.backtrace.each do |trace| %>
24
+ <span class="block"><%= trace %></span>
25
+ <% end %>
26
+ </div>
27
+ </div>
28
+ </div>
@@ -0,0 +1,16 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Error ready | <%= Rails.application.class.module_parent_name %></title>
5
+ <%= csrf_meta_tags %>
6
+ <%= csp_meta_tag %>
7
+
8
+ <%= stylesheet_link_tag "error_ready/application", media: "all" %>
9
+ <script src="https://cdn.tailwindcss.com"></script>
10
+ </head>
11
+ <body class="min-h-screen">
12
+ <div class="mx-auto md:max-w-4xl">
13
+ <%= yield %>
14
+ </div>
15
+ </body>
16
+ </html>
data/config/routes.rb ADDED
@@ -0,0 +1,3 @@
1
+ ErrorReady::Engine.routes.draw do
2
+ resources :problems
3
+ end
@@ -0,0 +1,16 @@
1
+ class CreateErrorReadyProblems < ActiveRecord::Migration[7.0]
2
+ def change
3
+ create_table :error_ready_problems do |t|
4
+ t.text :message
5
+ t.string :err_class
6
+ t.string :environment
7
+ t.string :severity
8
+ t.datetime :first_notice_at
9
+ t.datetime :last_notice_at
10
+ t.integer :notices_count
11
+ t.datetime :resolved_at
12
+
13
+ t.timestamps
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,11 @@
1
+ class CreateErrorReadyNotices < ActiveRecord::Migration[7.0]
2
+ def change
3
+ create_table :error_ready_notices do |t|
4
+ t.references :error_ready_problem, null: false, foreign_key: true
5
+ t.json :backtrace
6
+ t.json :context
7
+
8
+ t.timestamps
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module ErrorReady
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace ErrorReady
4
+
5
+ initializer "error_subscribe.error_ready" do |app|
6
+ Rails.error.subscribe(Subscriber.new)
7
+ # register midddleware
8
+ app.config.middleware.use(RackMiddleware)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,23 @@
1
+ module ErrorReady
2
+ class Formatter
3
+ def initialize(error:, handled:, severity:, context:, source: nil)
4
+ @error = error
5
+ @handled = handled
6
+ @severity = severity
7
+ @context = context
8
+ @source = source
9
+ end
10
+
11
+ def format
12
+ {
13
+ message: @error.message,
14
+ err_class: @error.class.to_s,
15
+ backtrace: @error.backtrace,
16
+ severity: @severity.to_s,
17
+ context: @context.transform_values(&:to_s),
18
+ source: @source,
19
+ environment: Rails.env
20
+ }
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,33 @@
1
+ module ErrorReady
2
+ class Database
3
+ def initialize(formatted_error)
4
+ @error = formatted_error
5
+ end
6
+
7
+ def call
8
+ problem = ErrorReady::Problem.find_or_create_by(
9
+ message: @error[:message],
10
+ err_class: @error[:err_class],
11
+ environment: @error[:environment],
12
+ severity: @error[:severity]
13
+ )
14
+
15
+ create_notice(problem)
16
+ end
17
+
18
+ def create_notice(problem)
19
+ ActiveRecord::Base.transaction do
20
+ ErrorReady::Notice.create(
21
+ problem: problem,
22
+ backtrace: @error[:backtrace],
23
+ context: @error[:context]
24
+ )
25
+
26
+ problem.update(
27
+ notices_count: problem.notices_count + 1,
28
+ last_notice_at: Time.current,
29
+ )
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,19 @@
1
+ module ErrorReady
2
+ class RackMiddleware
3
+ def initialize(app)
4
+ @app = app
5
+ end
6
+
7
+ def call(env)
8
+ Rails.error.set_context(
9
+ server_name: env["SERVER_NAME"],
10
+ http_host: env["HTTP_HOST"],
11
+ http_user_agent: env["HTTP_USER_AGENT"]
12
+ )
13
+
14
+ Rails.error.record do
15
+ @app.call(env)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,16 @@
1
+ module ErrorReady
2
+ class Subscriber
3
+ def report(error, handled:, severity:, context:, source: nil)
4
+ formatted_error = Formatter.new(
5
+ error: error,
6
+ handled: handled,
7
+ severity: severity,
8
+ context: context,
9
+ source: source
10
+ ).format
11
+
12
+ # Save to database
13
+ Database.new(formatted_error).call
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,3 @@
1
+ module ErrorReady
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,11 @@
1
+ require "error_ready/version"
2
+ require "error_ready/engine"
3
+
4
+ module ErrorReady
5
+ autoload :Subscriber, "error_ready/subscriber"
6
+ autoload :RackMiddleware, "error_ready/rack_middleware"
7
+ autoload :Formatter, 'error_ready/formatter'
8
+
9
+ # notifiers
10
+ autoload :Database, "error_ready/notifiers/database"
11
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :error_ready do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: error_ready
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Moses Gathuku
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-10-07 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.0.4
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 7.0.4
27
+ description: Description of ErrorReady.
28
+ email:
29
+ - mosesgathuku95@gmail.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - MIT-LICENSE
35
+ - README.md
36
+ - Rakefile
37
+ - app/assets/config/error_ready_manifest.js
38
+ - app/assets/images/error_ready/showcase.png
39
+ - app/assets/stylesheets/error_ready/application.css
40
+ - app/controllers/error_ready/application_controller.rb
41
+ - app/controllers/error_ready/problems_controller.rb
42
+ - app/helpers/error_ready/application_helper.rb
43
+ - app/helpers/error_ready/problems_helper.rb
44
+ - app/jobs/error_ready/application_job.rb
45
+ - app/mailers/error_ready/application_mailer.rb
46
+ - app/models/error_ready/application_record.rb
47
+ - app/models/error_ready/notice.rb
48
+ - app/models/error_ready/problem.rb
49
+ - app/views/error_ready/problems/_problem.html.erb
50
+ - app/views/error_ready/problems/index.html.erb
51
+ - app/views/error_ready/problems/show.html.erb
52
+ - app/views/layouts/error_ready/application.html.erb
53
+ - config/routes.rb
54
+ - db/migrate/20221005120809_create_error_ready_problems.rb
55
+ - db/migrate/20221005135120_create_error_ready_notices.rb
56
+ - lib/error_ready.rb
57
+ - lib/error_ready/engine.rb
58
+ - lib/error_ready/formatter.rb
59
+ - lib/error_ready/notifiers/database.rb
60
+ - lib/error_ready/rack_middleware.rb
61
+ - lib/error_ready/subscriber.rb
62
+ - lib/error_ready/version.rb
63
+ - lib/tasks/error_ready_tasks.rake
64
+ homepage: https://github.com/gathuku
65
+ licenses:
66
+ - MIT
67
+ metadata:
68
+ allowed_push_host: https://rubygems.org
69
+ homepage_uri: https://github.com/gathuku
70
+ source_code_uri: https://github.com/gathuku
71
+ changelog_uri: https://github.com/gathuku
72
+ post_install_message:
73
+ rdoc_options: []
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ requirements: []
87
+ rubygems_version: 3.3.7
88
+ signing_key:
89
+ specification_version: 4
90
+ summary: Summary of ErrorReady.
91
+ test_files: []