beekeeper 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ec711a53303d9fb0e5f4ee680e81e058ffc46e1652a91ca4bee3dcb05f7b81cc
4
+ data.tar.gz: 4efc54f12c5499769992c5d3e05f644d0b9fe8ff09369d31f2e9f82d8d1bf98b
5
+ SHA512:
6
+ metadata.gz: ad035c428b70925a0d27bd6aa4ed1373133009c1f806df0a1b93021e4f541146460d2deeace4cbdde664ab904e46844352f61a5976545dc0b34a0827715f390f
7
+ data.tar.gz: b62a386d0d7acb6270e247cb7c885211d00ca1fdf34c3498b8674e584b8b14097dc9a9e6d843118d62eb54adc15807b0926259ea8d702e81d28f3018d66a4725
@@ -0,0 +1,20 @@
1
+ Copyright 2020
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.
@@ -0,0 +1,48 @@
1
+ # Beekeeper
2
+ This is a library for error processing, logging and rendering.
3
+
4
+ ## Description
5
+
6
+ * This gem prints an error and a trimmed down version of the backtrace in case of ANY non-200 response in any application.
7
+ * This gem enables the application code(models, controllers and libs) code to be clean and concise. Since, now, we are handling the exceptions in a middleware, there is no need for ANY `re-raising exception` code in our models, controllers and other files.
8
+ * Application code should just contain the happy path and raise `known errors` if required. Other than that, no exception related code is required in the application code.
9
+ * This gem renders a standard JSON error response in case there is any error when calling an API route (`/api`). Currently, if there is any error, an HTML response is returned even if a JSON API route is called.
10
+
11
+
12
+ ## Installation
13
+ Add this line to your application's Gemfile:
14
+
15
+ ```ruby
16
+ gem 'beekeeper'
17
+ ```
18
+
19
+ And then execute:
20
+ ```bash
21
+ $ bundle
22
+ ```
23
+
24
+ Or install it yourself as:
25
+ ```bash
26
+ $ gem install beekeeper
27
+ ```
28
+
29
+ ## Usage
30
+
31
+ * Include `Beekeeper::Rescuer` in your application controller so that known errors are logged and response is returned in a standard JSON format.
32
+ * These are the `known errors` it rescues:
33
+ * `CustomErrors`
34
+ * `BaseError`
35
+ * `ActiveRecord::RecordInvalid` (Validation errors)
36
+ * `ActiveRecord::RecordNotFound`
37
+
38
+ * This library also inserts a `TrapApiExceptions` middleware in your Rails application stack which traps errors from an API route (`/api`) and returns a standard JSON error response by default. (Without this middleware, an HTML response is returned)
39
+
40
+ ## Usage
41
+
42
+ * Define `CustomErrors` in this gem and let other Rails apps inherit or use this in their apps.
43
+
44
+ ## Contributing
45
+ Contribution directions go here.
46
+
47
+ ## License
48
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,27 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'Beekeeper'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ require 'bundler/gem_tasks'
18
+
19
+ require 'rake/testtask'
20
+
21
+ Rake::TestTask.new(:test) do |t|
22
+ t.libs << 'test'
23
+ t.pattern = 'test/**/*_test.rb'
24
+ t.verbose = false
25
+ end
26
+
27
+ task default: :test
@@ -0,0 +1,5 @@
1
+ require "beekeeper/railtie"
2
+ require "beekeeper/rescuer"
3
+ require "beekeeper/trap_api_exceptions"
4
+ require "beekeeper/error"
5
+ require "beekeeper/logger"
@@ -0,0 +1,32 @@
1
+ module Beekeeper
2
+ class Error < StandardError
3
+
4
+ attr_reader :status_code, :errors, :data, :status
5
+
6
+ def initialize(status_code, msg, options = {})
7
+ super(msg)
8
+ @status_code = status_code
9
+ @errors = get_errors(options)
10
+ @data = options[:data] || {}
11
+ @status = @status_code
12
+ end
13
+
14
+ def get_errors(options)
15
+ return [options.delete(:error)] if options[:error].present?
16
+ return options[:errors].errors().messages() if options[:errors].class < ActiveRecord::Base
17
+ return options[:error_map] if options[:error_map]
18
+ return options[:errors] || [{
19
+ code: class_name(options),
20
+ message: self.message
21
+ }]
22
+ end
23
+
24
+ private
25
+
26
+ def class_name options
27
+ return options[:exception].class.to_s if options[:exception].present?
28
+ self.class.to_s
29
+ end
30
+ end
31
+ end
32
+
@@ -0,0 +1,51 @@
1
+ require 'blueprinter'
2
+ module Beekeeper
3
+ class ExceptionBlueprinter < Blueprinter::Base
4
+
5
+ view :basic do
6
+ field :status do |exception, options|
7
+ exception.try(:status) || get_status(exception, options)
8
+ end
9
+ field :message
10
+ field :error do |exception, options|
11
+ exception.try(:error) || get_error(exception, options)
12
+ end
13
+ field :errors do |exception, options|
14
+ exception.try(:errors) || get_errors(exception)
15
+ end
16
+ field :data do |exception, options|
17
+ exception.try(:data) || {}
18
+ end
19
+ end
20
+
21
+ def self.get_status exception, options
22
+ exception.try(:status) || get_status_from_backtrace(exception, options)
23
+ end
24
+
25
+ def self.get_error exception, options
26
+ status = get_status exception, options
27
+ Rack::Utils::HTTP_STATUS_CODES.fetch(status, Rack::Utils::HTTP_STATUS_CODES[500])
28
+ end
29
+
30
+ def self.get_status_from_backtrace exception, options
31
+ request = options[:request]
32
+ backtrace_cleaner = request.env['action_dispatch.backtrace_cleaner']
33
+ wrapper = ::ActionDispatch::ExceptionWrapper.new(backtrace_cleaner, exception)
34
+ return wrapper.status_code
35
+ end
36
+
37
+ def self.get_errors exception
38
+ return [
39
+ {
40
+ code: exception.class.name,
41
+ message: exception.message
42
+ }
43
+ ]
44
+ end
45
+
46
+ private
47
+
48
+
49
+ end
50
+ end
51
+
@@ -0,0 +1,37 @@
1
+ module Beekeeper
2
+ class Logger
3
+ def self.fatal(error)
4
+ message = if error.respond_to? :backtrace
5
+ message_with_backtrace(error)
6
+ else
7
+ error
8
+ end
9
+ Rails.logger.fatal message
10
+ end
11
+
12
+ def self.error(error)
13
+ message = if error.respond_to? :backtrace
14
+ message_with_backtrace(error)
15
+ else
16
+ error
17
+ end
18
+ Rails.logger.error message
19
+ end
20
+
21
+ private
22
+
23
+ def self.message_with_backtrace(error)
24
+ trace = clean(error.backtrace)
25
+ "\n#{error.class.name} (#{error.message}):\n#{trace.join}"
26
+ end
27
+
28
+ def self.clean(backtrace)
29
+ bc = ActiveSupport::BacktraceCleaner.new
30
+ bc.add_filter { |line| line.gsub(Rails.root.to_s, '') } # strip the Rails.root prefix
31
+ bc.add_silencer { |line| line =~ /puma|rubygems|vendor|bin/ } # skip any lines from puma or rubygems
32
+ bc.clean(backtrace).map! { |t| " #{t}\n" }
33
+ end
34
+
35
+ end
36
+ end
37
+
@@ -0,0 +1,4 @@
1
+ module Beekeeper
2
+ class Railtie < ::Rails::Railtie
3
+ end
4
+ end
@@ -0,0 +1,26 @@
1
+ require 'beekeeper/exception_blueprinter'
2
+ module Beekeeper
3
+ module Rescuer
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ RESCUABLE_ERRORS = [
8
+ ::Beekeeper::Error,
9
+ ::Apipie::Error,
10
+ ::ActiveRecord::RecordInvalid
11
+ ]
12
+
13
+ rescue_from(*RESCUABLE_ERRORS, with: :handle_error)
14
+
15
+ def handle_error(error)
16
+ Logger.error(error)
17
+ response = ExceptionBlueprinter.render_as_hash error, view: :basic, request: request
18
+ render json: response, status: response[:status]
19
+ end
20
+
21
+ end
22
+
23
+ end
24
+ end
25
+
26
+
@@ -0,0 +1,60 @@
1
+ require 'beekeeper/exception_blueprinter'
2
+ class Beekeeper::Railtie
3
+ initializer 'beekeeper.trap_api_exceptions' do |app|
4
+ # Global exception handler. No need of any exception handling in the application code.
5
+ app.middleware.insert_after(ActionDispatch::ShowExceptions, Beekeeper::TrapApiExceptions)
6
+ end
7
+ end
8
+
9
+ module Beekeeper
10
+ class TrapApiExceptions
11
+ def initialize(app)
12
+ @app = app
13
+ end
14
+
15
+ def call(env)
16
+ request = ActionDispatch::Request.new env
17
+ @app.call(env)
18
+ rescue StandardError => e
19
+ if request.path_info.include? '/api'
20
+ render_json_error(request, e)
21
+ else
22
+ raise e
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def render_json_error(request, exception)
29
+ response = ExceptionBlueprinter.render_as_hash(exception, view: :basic, request: request)
30
+ body = response.to_json
31
+ return [
32
+ response[:status],
33
+ {
34
+ 'Content-Type' => "json; charset=#{::ActionDispatch::Response.default_charset}",
35
+ 'Content-Length' => body.bytesize.to_s
36
+ },
37
+ [body]
38
+ ]
39
+ end
40
+
41
+ def get_status(request, exception)
42
+ backtrace_cleaner = request.get_header 'action_dispatch.backtrace_cleaner'
43
+ wrapper = ::ActionDispatch::ExceptionWrapper.new(backtrace_cleaner, exception)
44
+ return wrapper.status_code
45
+ end
46
+
47
+ def get_error(status)
48
+ Rack::Utils::HTTP_STATUS_CODES.fetch(status, Rack::Utils::HTTP_STATUS_CODES[500])
49
+ end
50
+
51
+ def get_errors(exception)
52
+ return [
53
+ {
54
+ code: exception.class.name,
55
+ message: exception.message
56
+ }
57
+ ]
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,3 @@
1
+ module Beekeeper
2
+ VERSION = '0.1.7'
3
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :beekeeper do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: beekeeper
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.7
5
+ platform: ruby
6
+ authors:
7
+ - Omkar Joshi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-08-26 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: 5.1.4
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 5.1.4
27
+ - !ruby/object:Gem::Dependency
28
+ name: blueprinter
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.23.4
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.23.4
41
+ - !ruby/object:Gem::Dependency
42
+ name: oj
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 3.10.6
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 3.10.6
55
+ description: 'Beekeepeer: This gem is responsible for error logging, processing and
56
+ rendering of errors in a standard JSON format..'
57
+ email:
58
+ - omkar.joshi@anarock.com
59
+ executables: []
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - MIT-LICENSE
64
+ - README.md
65
+ - Rakefile
66
+ - lib/beekeeper.rb
67
+ - lib/beekeeper/error.rb
68
+ - lib/beekeeper/exception_blueprinter.rb
69
+ - lib/beekeeper/logger.rb
70
+ - lib/beekeeper/railtie.rb
71
+ - lib/beekeeper/rescuer.rb
72
+ - lib/beekeeper/trap_api_exceptions.rb
73
+ - lib/beekeeper/version.rb
74
+ - lib/tasks/beekeeper_tasks.rake
75
+ homepage: https://github.com/saas-bn/beekeeper
76
+ licenses:
77
+ - MIT
78
+ metadata:
79
+ allowed_push_host: https://rubygems.org
80
+ post_install_message:
81
+ rdoc_options: []
82
+ require_paths:
83
+ - lib
84
+ required_ruby_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ requirements: []
95
+ rubygems_version: 3.0.3
96
+ signing_key:
97
+ specification_version: 4
98
+ summary: 'Beekeeper: Error logging, processing and rendering.'
99
+ test_files: []