exceptio 0.2.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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +63 -0
- data/Rakefile +37 -0
- data/app/assets/config/exceptio_manifest.js +2 -0
- data/app/assets/javascripts/exceptio/application.js +2 -0
- data/app/assets/stylesheets/exceptio/application.css +15 -0
- data/app/controllers/exceptio/application_controller.rb +7 -0
- data/app/controllers/exceptio/exceptions_controller.rb +27 -0
- data/app/drops/exceptio/application_drop.rb +17 -0
- data/app/drops/exceptio/exception_drop.rb +9 -0
- data/app/drops/exceptio/instance_drop.rb +5 -0
- data/app/helpers/exceptio/application_helper.rb +13 -0
- data/app/jobs/exceptio/application_job.rb +4 -0
- data/app/mailers/exceptio/application_mailer.rb +6 -0
- data/app/models/exceptio/application_record.rb +9 -0
- data/app/models/exceptio/exception.rb +19 -0
- data/app/models/exceptio/instance.rb +44 -0
- data/app/services/exceptio/application_service.rb +22 -0
- data/app/services/exceptio/backtrace_enrichment_service.rb +59 -0
- data/app/services/exceptio/exception_recording_service.rb +51 -0
- data/app/tables/exceptio/exceptions_table.rb +58 -0
- data/app/views/exceptio/exception.html.slim +101 -0
- data/app/views/exceptio/exceptions/_trace_element.html.slim +15 -0
- data/app/views/exceptio/exceptions/index.html.slim +5 -0
- data/app/views/exceptio/exceptions/show.html.slim +74 -0
- data/app/views/exceptio/instances/_instance.html.slim +48 -0
- data/config/importmap.rb +4 -0
- data/config/locales/en.yml +16 -0
- data/config/locales/nl.yml +16 -0
- data/config/routes.rb +10 -0
- data/db/migrate/20190729153259_create_exceptions.rb +23 -0
- data/db/migrate/20201027102223_add_indices1.rb +8 -0
- data/db/migrate/20221229092150_add_ownable_to_instance.rb +6 -0
- data/lib/exceptio/engine.rb +28 -0
- data/lib/exceptio/rack/rails_instrumentation.rb +52 -0
- data/lib/exceptio/railtie.rb +19 -0
- data/lib/exceptio/recording.rb +92 -0
- data/lib/exceptio/version.rb +5 -0
- data/lib/exceptio.rb +69 -0
- metadata +222 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: eab876be6f5e91e98ecebaca6bc0ebfea71a342cf4f0960257e1e8426407a52a
|
|
4
|
+
data.tar.gz: 4cb5945dcf630db3e73706e21aa96b784d3574f99897058e464ee55f8c0d5cec
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: a32a5553c4b6dab7bc27264a7b243335650e2727ddae8f968a9ae18613d71994f24a0059a6746e9d5fe5243cad21575968d78f2f11c766aa865b076ee10ec986
|
|
7
|
+
data.tar.gz: a9b668449d6c0497e7e5cdcfd8aaaeb99905fc6ec5257cca2c863b63467a506753c269cf286888f86f969531137fe810575f21028129ef58b01336f94f9e6352
|
data/MIT-LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright 2018 Tom de Grunt
|
|
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,63 @@
|
|
|
1
|
+
# Exceptio
|
|
2
|
+
|
|
3
|
+
Exception logging and management
|
|
4
|
+
|
|
5
|
+
## What it looks like
|
|
6
|
+
|
|
7
|
+
The list view shows you all the exceptions we caught.
|
|
8
|
+
|
|
9
|
+

|
|
10
|
+
|
|
11
|
+
We have a detail view, which shows you the exception that happens and the instances it happened, up to 100.
|
|
12
|
+
It also shows you a graph of when these instances happened.
|
|
13
|
+
|
|
14
|
+

|
|
15
|
+
|
|
16
|
+
## Installation and Usage
|
|
17
|
+
|
|
18
|
+
Add this line to your application's Gemfile:
|
|
19
|
+
|
|
20
|
+
```ruby
|
|
21
|
+
gem 'exceptio'
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Add to ApplicationController
|
|
25
|
+
|
|
26
|
+
`rescue_from StandardError, with: :error_render_method`
|
|
27
|
+
|
|
28
|
+
```ruby
|
|
29
|
+
def error_render_method(exception)
|
|
30
|
+
Exceptio::ExceptionRecordingService.new(exception, request_env: request.env).call
|
|
31
|
+
|
|
32
|
+
respond_to do |type|
|
|
33
|
+
type.html do
|
|
34
|
+
begin
|
|
35
|
+
render template: "/exceptio/exception", layout: false, status: 500
|
|
36
|
+
rescue
|
|
37
|
+
render template: "/exceptio/exception", layout: false, status: 500
|
|
38
|
+
end
|
|
39
|
+
false
|
|
40
|
+
end
|
|
41
|
+
type.js { render json: { error: 'internal server error' }, status: 500 }
|
|
42
|
+
type.all { render nothing: true, status: 500 }
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Next add to the route.rb:
|
|
48
|
+
|
|
49
|
+
```ruby
|
|
50
|
+
mount Exceptio::Engine => "/exceptions"
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Run the Rails tasks to install and run the migrations:
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
bin/rails exceptio:install:migrations
|
|
57
|
+
bin/rails db:migrate
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
## License
|
|
62
|
+
|
|
63
|
+
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,37 @@
|
|
|
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 = 'Exceptio'
|
|
12
|
+
rdoc.options << '--line-numbers'
|
|
13
|
+
rdoc.rdoc_files.include('README.md')
|
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
|
|
18
|
+
load 'rails/tasks/engine.rake'
|
|
19
|
+
|
|
20
|
+
load 'rails/tasks/statistics.rake'
|
|
21
|
+
|
|
22
|
+
require 'bundler/gem_tasks'
|
|
23
|
+
|
|
24
|
+
require 'rake/testtask'
|
|
25
|
+
|
|
26
|
+
Rake::TestTask.new(:test) do |t|
|
|
27
|
+
t.libs << 'test'
|
|
28
|
+
t.pattern = 'test/**/*_test.rb'
|
|
29
|
+
t.verbose = false
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
task default: :test
|
|
33
|
+
|
|
34
|
+
# Adds the Auxilium semver task
|
|
35
|
+
spec = Gem::Specification.find_by_name 'auxilium'
|
|
36
|
+
load "#{spec.gem_dir}/lib/tasks/semver.rake"
|
|
37
|
+
|
|
@@ -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,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# require_dependency 'exceptio/application_controller'
|
|
4
|
+
|
|
5
|
+
module Exceptio
|
|
6
|
+
class ExceptionsController < ::Exceptio::ApplicationController
|
|
7
|
+
def index
|
|
8
|
+
redirect_to main_app.root_path unless Current.user && (Current.user.is_admin? || Current.user.is_billing_admin?)
|
|
9
|
+
@exceptions = ::Exceptio::Exception.all.order(updated_at: :desc)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def show
|
|
13
|
+
@exception = ::Exceptio::Exception.find(params[:id])
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def destroy
|
|
17
|
+
@exception = ::Exceptio::Exception.find(params[:id])
|
|
18
|
+
@exception.destroy
|
|
19
|
+
redirect_to action: :index, status: :see_other
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def delete_all
|
|
23
|
+
::Exceptio::Exception.destroy_all
|
|
24
|
+
redirect_to action: :index, status: :see_other
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Exceptio
|
|
4
|
+
class Exception < ApplicationRecord
|
|
5
|
+
has_many :instances, dependent: :destroy
|
|
6
|
+
|
|
7
|
+
delegate :message, to: :last_instance
|
|
8
|
+
|
|
9
|
+
def last_instance
|
|
10
|
+
instances.order(created_at: :desc).first
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
class << self
|
|
14
|
+
def for(exception)
|
|
15
|
+
where(exception_class: exception.class.name, code_location: exception.backtrace.first).first_or_initialize
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Exceptio
|
|
4
|
+
class Instance < ApplicationRecord
|
|
5
|
+
belongs_to :exception, counter_cache: true, touch: :last_instance_at
|
|
6
|
+
belongs_to :exceptio_exceptionable, polymorphic: true, optional: true
|
|
7
|
+
|
|
8
|
+
def related_objects
|
|
9
|
+
related_data.map(&:first).compact
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def related_data
|
|
13
|
+
related_sgids.map { |sgid| Exceptio.config.sgid_to_object_url_name(sgid) }.compact
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def browser
|
|
17
|
+
return nil unless request_env
|
|
18
|
+
|
|
19
|
+
Browser.new(request_env['HTTP_USER_AGENT'], accept_language: request_env['HTTP_ACCEPT_LANGUAGE'])
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def request_env
|
|
23
|
+
return {} unless context.key?('request_env')
|
|
24
|
+
|
|
25
|
+
JSON.parse(context['request_env'])
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def job
|
|
29
|
+
return {} unless context.key?('job')
|
|
30
|
+
|
|
31
|
+
JSON.parse(context['job'])
|
|
32
|
+
rescue
|
|
33
|
+
eval(context['job']) # Yuk
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def job?
|
|
37
|
+
context.key?('job')
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def web?
|
|
41
|
+
context.key?('request_env')
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Exceptio
|
|
4
|
+
class ApplicationService
|
|
5
|
+
def call
|
|
6
|
+
perform
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
private
|
|
10
|
+
|
|
11
|
+
def log(level, message)
|
|
12
|
+
message = "#{self.class.name}: #{message}"
|
|
13
|
+
Exceptio.logger.public_send level, message
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
class << self
|
|
17
|
+
def call
|
|
18
|
+
new.call
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Exceptio
|
|
4
|
+
class BacktraceEnrichmentService < ApplicationService
|
|
5
|
+
attr_reader :backtrace
|
|
6
|
+
delegate :gems_data, to: :class
|
|
7
|
+
|
|
8
|
+
def initialize(backtrace)
|
|
9
|
+
@backtrace = backtrace.is_a?(Array) ? backtrace : backtrace.split("\n")
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def perform
|
|
13
|
+
backtrace.map { |line| line_details(line) }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def line_details(line)
|
|
17
|
+
data = gem_data_for(line)
|
|
18
|
+
data ||= extract_data_for(line)
|
|
19
|
+
|
|
20
|
+
data[:file], data[:line], data[:method] = data.delete(:local_path).split(':', 3)
|
|
21
|
+
data[:method] = data[:method]&.gsub('in `', '')&.gsub("'", '')
|
|
22
|
+
data[:full_line] = line
|
|
23
|
+
data
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Find the relevant gem information
|
|
27
|
+
def gem_data_for(line)
|
|
28
|
+
gem_path = gems_data.keys.find { |gem_path| gem_path.starts_with?('/') ? line.starts_with?(gem_path) : line.include?(gem_path)}
|
|
29
|
+
gem_data = gems_data[gem_path].dup
|
|
30
|
+
gem_data[:local_path] = line.gsub(%r{.*#{gem_path}\/?}, '') if gem_data
|
|
31
|
+
gem_data
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Extract info from line when gem data is missing
|
|
35
|
+
def extract_data_for(line)
|
|
36
|
+
if line =~ /\([a-zA-Z_]+\)/
|
|
37
|
+
{ name: line.split('(', 2).last.split(')').first, version: '', local_path: line }
|
|
38
|
+
else
|
|
39
|
+
{ name: '(unkown)', version: '', local_path: line }
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
class << self
|
|
44
|
+
# Retrieve data about bundled gems, ruby and the rails app
|
|
45
|
+
def gems_data
|
|
46
|
+
return @gems if @gems
|
|
47
|
+
|
|
48
|
+
@gems = {}
|
|
49
|
+
@gems = Bundler.load.gems.map { |gem| [gem.full_gem_path, { name: gem.name, version: gem.version.to_s }] }.to_h
|
|
50
|
+
@gems[Bundler.ruby_scope.to_s] = { name: 'Ruby', version: RUBY_VERSION }
|
|
51
|
+
@gems[Rails.root.to_s] = { name: Rails.application.class.name, version: `git rev-parse --short HEAD`.chomp }
|
|
52
|
+
@gems['./'] = { name: Rails.application.class.name, version: `git rev-parse --short HEAD`.chomp }
|
|
53
|
+
@gems
|
|
54
|
+
rescue StandardError
|
|
55
|
+
@gems
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Exceptio
|
|
4
|
+
class ExceptionRecordingService < ApplicationService
|
|
5
|
+
attr_reader :exception, :context
|
|
6
|
+
|
|
7
|
+
def initialize(exception, context = {})
|
|
8
|
+
@exception = exception
|
|
9
|
+
@context = context
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def perform
|
|
13
|
+
log :error, "processing exception: #{exception.message}"
|
|
14
|
+
# raise exception if Rails.env.test?
|
|
15
|
+
|
|
16
|
+
model = ::Exceptio::Exception.for(exception)
|
|
17
|
+
|
|
18
|
+
if model.instances.size >= Exceptio.config.max_occurences
|
|
19
|
+
model.touch(:updated_at)
|
|
20
|
+
return model.id
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Always update the backtrace, versions, code locations might change, want to deal with the latest only.
|
|
24
|
+
model.detailed_backtrace = BacktraceEnrichmentService.new(exception.backtrace).call
|
|
25
|
+
|
|
26
|
+
instance = model.instances.build(
|
|
27
|
+
message: exception.message,
|
|
28
|
+
related_sgids: Exceptio.config.related_sgids || [],
|
|
29
|
+
context: Exceptio.config.context_details.merge(context).map {|k, v| [k, JSON.dump(v)] }.to_h
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
if exception.try(:record)
|
|
33
|
+
instance.exceptio_exceptionable = exception.record
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
model.save!
|
|
37
|
+
|
|
38
|
+
Exceptio.config.after_exception(model, instance)
|
|
39
|
+
|
|
40
|
+
model.id
|
|
41
|
+
rescue StandardError => outer_exception
|
|
42
|
+
Rails.logger.error '=' * 80
|
|
43
|
+
Rails.logger.error "EXCEPTION SAVING EXCEPTION: #{outer_exception.message} DURING CAPTURE OF #{exception&.message}"
|
|
44
|
+
Rails.logger.error "Outer: #{outer_exception.message}\n#{outer_exception.backtrace.join("\n")}"
|
|
45
|
+
Rails.logger.error '-' * 80
|
|
46
|
+
Rails.logger.error "Inner: #{exception&.message}\n#{exception&.backtrace&.join("\n")}"
|
|
47
|
+
Rails.logger.error '=' * 80
|
|
48
|
+
model&.id
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Exceptio::ExceptionsTable < Mensa::Base
|
|
4
|
+
definition do
|
|
5
|
+
model Exceptio::Exception
|
|
6
|
+
|
|
7
|
+
column(:exception_class)
|
|
8
|
+
column(:message) do
|
|
9
|
+
render do
|
|
10
|
+
html do |exception|
|
|
11
|
+
exception.message.to_s.truncate(40)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
column(:code_location) do
|
|
16
|
+
render do
|
|
17
|
+
html do |exception|
|
|
18
|
+
exception.code_location.to_s.gsub(Rails.root.to_s, '').truncate(20)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
column(:count) do
|
|
23
|
+
render do
|
|
24
|
+
html do |exception|
|
|
25
|
+
exception.instances.size
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
column(:last_instance_at) do
|
|
30
|
+
render do
|
|
31
|
+
html do |exception|
|
|
32
|
+
ln exception.last_instance_at
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
# column(:actions) { |exception| link_to '<i class="fal fa-trash"></i>'.html_safe, exceptio.exception_path(exception), data: { turbo_method: :delete }}
|
|
37
|
+
|
|
38
|
+
# column(:) do
|
|
39
|
+
# render do
|
|
40
|
+
# html do |screening|
|
|
41
|
+
# screening.profiles.join(",")
|
|
42
|
+
# end
|
|
43
|
+
# end
|
|
44
|
+
# end
|
|
45
|
+
|
|
46
|
+
order last_instance_at: "desc"
|
|
47
|
+
|
|
48
|
+
link { |exception| exceptio.exception_path(exception) }
|
|
49
|
+
|
|
50
|
+
# filter(:query) { |value| where('id::text ILIKE :query', query: "#{value}%") }
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
private
|
|
54
|
+
|
|
55
|
+
def scope
|
|
56
|
+
@scope ||= Exceptio::Exception.all
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
doctype html
|
|
2
|
+
html lang="en"
|
|
3
|
+
head
|
|
4
|
+
title We're sorry, but something went wrong (500 Internal Server Error)
|
|
5
|
+
meta charset="utf-8"
|
|
6
|
+
meta name="viewport" content="initial-scale=1, width=device-width"
|
|
7
|
+
meta name="robots" content="noindex, nofollow"
|
|
8
|
+
css:
|
|
9
|
+
*, *::before, *::after {
|
|
10
|
+
box-sizing: border-box;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
* {
|
|
14
|
+
margin: 0;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
html {
|
|
18
|
+
font-size: 16px;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
body {
|
|
22
|
+
background: #FFF;
|
|
23
|
+
color: #261B23;
|
|
24
|
+
display: grid;
|
|
25
|
+
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Aptos, Roboto, "Segoe UI", "Helvetica Neue", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
|
26
|
+
font-size: clamp(1rem, 2.5vw, 2rem);
|
|
27
|
+
-webkit-font-smoothing: antialiased;
|
|
28
|
+
font-style: normal;
|
|
29
|
+
font-weight: 400;
|
|
30
|
+
letter-spacing: -0.0025em;
|
|
31
|
+
line-height: 1.4;
|
|
32
|
+
min-height: 100vh;
|
|
33
|
+
place-items: center;
|
|
34
|
+
text-rendering: optimizeLegibility;
|
|
35
|
+
-webkit-text-size-adjust: 100%;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
a {
|
|
39
|
+
color: inherit;
|
|
40
|
+
font-weight: 700;
|
|
41
|
+
text-decoration: underline;
|
|
42
|
+
text-underline-offset: 0.0925em;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
b, strong {
|
|
46
|
+
font-weight: 700;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
i, em {
|
|
50
|
+
font-style: italic;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
main {
|
|
54
|
+
display: grid;
|
|
55
|
+
gap: 1em;
|
|
56
|
+
padding: 2em;
|
|
57
|
+
place-items: center;
|
|
58
|
+
text-align: center;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
main header {
|
|
62
|
+
width: min(100%, 12em);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
main header svg {
|
|
66
|
+
height: auto;
|
|
67
|
+
max-width: 100%;
|
|
68
|
+
width: 100%;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
main article {
|
|
72
|
+
width: min(100%, 30em);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
main article p {
|
|
76
|
+
font-size: 75%;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
main article br {
|
|
80
|
+
|
|
81
|
+
display: none;
|
|
82
|
+
|
|
83
|
+
@media(min-width: 48em) {
|
|
84
|
+
display: inline;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
body
|
|
90
|
+
main
|
|
91
|
+
header
|
|
92
|
+
svg height="172" viewBox="0 0 480 172" width="480" xmlns="http://www.w3.org/2000/svg"><path d="m101.23 93.8427c-8.1103 0-15.4098 3.7849-19.7354 8.3813h-36.2269v-99.21891h103.8143v37.03791h-68.3984v24.8722c5.1366-2.7035 15.1396-5.9477 24.6014-5.9477 35.146 0 56.233 22.7094 56.233 55.4215 0 34.605-23.791 57.315-60.558 57.315-37.8492 0-61.64-22.169-63.8028-55.963h42.9857c1.0814 10.814 9.1919 19.195 21.6281 19.195 11.355 0 19.465-8.381 19.465-20.547 0-11.625-7.299-20.5463-20.006-20.5463zm138.833 77.8613c-40.822 0-64.884-35.146-64.884-85.7015 0-50.5554 24.062-85.700907 64.884-85.700907 40.823 0 64.884 35.145507 64.884 85.700907 0 50.5555-24.061 85.7015-64.884 85.7015zm0-133.2831c-17.572 0-22.709 21.8984-22.709 47.5816 0 25.6835 5.137 47.5815 22.709 47.5815 17.303 0 22.71-21.898 22.71-47.5815 0-25.6832-5.407-47.5816-22.71-47.5816zm140.456 133.2831c-40.823 0-64.884-35.146-64.884-85.7015 0-50.5554 24.061-85.700907 64.884-85.700907 40.822 0 64.884 35.145507 64.884 85.700907 0 50.5555-24.062 85.7015-64.884 85.7015zm0-133.2831c-17.573 0-22.71 21.8984-22.71 47.5816 0 25.6835 5.137 47.5815 22.71 47.5815 17.302 0 22.709-21.898 22.709-47.5815 0-25.6832-5.407-47.5816-22.709-47.5816z" fill="#f0eff0"/><path d="m23.1377 68.9967v34.0033h-8.9162v-34.0033zm4.3157 34.0033v-24.921h8.6947v2.1598c1.3845-1.5506 3.8212-2.7136 6.701-2.7136 5.538 0 8.8054 3.5997 8.8054 9.1377v16.3371h-8.6393v-14.2327c0-2.049-1.0522-3.5443-3.2674-3.5443-1.7168 0-3.1567.9969-3.5997 2.7136v15.0634zm29.9913-8.5839v-9.5807h-3.655v-6.7564h3.655v-6.8671h8.5839v6.8671h5.2058v6.7564h-5.2058v8.307c0 1.9383.9415 2.769 2.6583 2.769.9414 0 1.9937-.2216 2.769-.5538v7.3654c-.9969.443-2.8798.775-4.8181.775-5.8703 0-9.1931-2.769-9.1931-9.0819zm32.3666-.1108h8.0301c-.8861 5.7597-5.2057 9.2487-11.6852 9.2487-7.6424 0-12.682-5.2613-12.682-13.0145 0-7.6978 5.3165-13.0143 12.5159-13.0143 7.6424 0 11.9621 5.095 11.9621 12.5159v2.1598h-16.1156c.2769 2.9905 1.8275 4.5965 4.3196 4.5965 1.7722 0 3.1567-.7753 3.6551-2.4921zm-3.8212-10.0237c-2.0491 0-3.4336 1.2737-3.9874 3.5997h7.5317c-.1107-2.0491-1.3845-3.5997-3.5443-3.5997zm31.4299-6.3134v8.3624c-1.052-.5538-2.215-.7753-3.599-.7753-2.382 0-3.988 1.0522-4.431 2.8244v14.6203h-8.694v-24.921h8.694v2.2152c1.219-1.6614 3.157-2.769 5.649-2.769 1.108 0 1.994.2215 2.381.443zm2.949 25.0318v-24.921h8.694v2.1598c1.385-1.5506 3.821-2.7136 6.701-2.7136 5.538 0 8.806 3.5997 8.806 9.1377v16.3371h-8.64v-14.2327c0-2.049-1.052-3.5443-3.267-3.5443-1.717 0-3.157.9969-3.6 2.7136v15.0634zm50.371 0h-8.363v-1.274c-.83.831-3.323 1.717-5.981 1.717-4.929 0-9.082-2.769-9.082-8.0301 0-4.818 4.153-7.9193 9.581-7.9193 2.049 0 4.485.6646 5.482 1.3845v-1.606c0-1.606-.941-2.9905-3.046-2.9905-1.606 0-2.547.7199-2.935 1.8275h-8.196c.72-4.8181 4.984-8.6393 11.408-8.6393 7.089 0 11.132 3.7659 11.132 10.2453zm-8.363-6.9779v-1.4399c-.554-1.0522-2.049-1.7167-3.655-1.7167-1.717 0-3.433.7199-3.433 2.3813 0 1.7168 1.716 2.4367 3.433 2.4367 1.606 0 3.101-.6645 3.655-1.6614zm20.742-29.0191v35.997h-8.694v-35.997zm13.036 25.9178h9.248c.72 2.326 2.714 3.489 5.483 3.489 2.713 0 4.596-1.163 4.596-3.2674 0-1.6061-1.052-2.326-3.212-2.8244l-6.534-1.3845c-4.985-1.1076-8.751-3.7105-8.751-9.47 0-6.6456 5.538-11.0206 13.07-11.0206 8.307 0 13.014 4.5411 13.956 10.4114h-8.695c-.72-1.8829-2.27-3.3228-5.205-3.3228-2.548 0-4.265 1.1076-4.265 2.9905 0 1.4953 1.052 2.326 2.825 2.7137l6.645 1.5506c5.815 1.3845 9.027 4.5412 9.027 9.8023 0 6.9778-5.87 10.9654-13.291 10.9654-8.141 0-13.679-3.9322-14.897-10.6332zm46.509 1.3845h8.031c-.887 5.7597-5.206 9.2487-11.686 9.2487-7.642 0-12.682-5.2613-12.682-13.0145 0-7.6978 5.317-13.0143 12.516-13.0143 7.643 0 11.962 5.095 11.962 12.5159v2.1598h-16.115c.277 2.9905 1.827 4.5965 4.319 4.5965 1.773 0 3.157-.7753 3.655-2.4921zm-3.821-10.0237c-2.049 0-3.433 1.2737-3.987 3.5997h7.532c-.111-2.0491-1.385-3.5997-3.545-3.5997zm31.431-6.3134v8.3624c-1.053-.5538-2.216-.7753-3.6-.7753-2.381 0-3.988 1.0522-4.431 2.8244v14.6203h-8.694v-24.921h8.694v2.2152c1.219-1.6614 3.157-2.769 5.649-2.769 1.108 0 1.994.2215 2.382.443zm18.288 25.0318h-7.809l-9.47-24.921h8.861l4.763 14.288 4.652-14.288h8.528zm25.614-8.6947h8.03c-.886 5.7597-5.206 9.2487-11.685 9.2487-7.642 0-12.682-5.2613-12.682-13.0145 0-7.6978 5.316-13.0143 12.516-13.0143 7.642 0 11.962 5.095 11.962 12.5159v2.1598h-16.116c.277 2.9905 1.828 4.5965 4.32 4.5965 1.772 0 3.157-.7753 3.655-2.4921zm-3.821-10.0237c-2.049 0-3.434 1.2737-3.988 3.5997h7.532c-.111-2.0491-1.384-3.5997-3.544-3.5997zm31.43-6.3134v8.3624c-1.052-.5538-2.215-.7753-3.6-.7753-2.381 0-3.987 1.0522-4.43 2.8244v14.6203h-8.695v-24.921h8.695v2.2152c1.218-1.6614 3.157-2.769 5.649-2.769 1.107 0 1.993.2215 2.381.443zm13.703-8.9715h24.312v7.6424h-15.562v5.3165h14.232v7.4763h-14.232v5.8703h15.562v7.6978h-24.312zm44.667 8.9715v8.3624c-1.052-.5538-2.215-.7753-3.6-.7753-2.381 0-3.987 1.0522-4.43 2.8244v14.6203h-8.695v-24.921h8.695v2.2152c1.218-1.6614 3.156-2.769 5.648-2.769 1.108 0 1.994.2215 2.382.443zm19.673 0v8.3624c-1.053-.5538-2.216-.7753-3.6-.7753-2.381 0-3.987 1.0522-4.43 2.8244v14.6203h-8.695v-24.921h8.695v2.2152c1.218-1.6614 3.156-2.769 5.648-2.769 1.108 0 1.994.2215 2.382.443zm26.769 12.5713c0 7.6978-5.15 13.0145-12.737 13.0145-7.532 0-12.738-5.3167-12.738-13.0145s5.206-13.0143 12.738-13.0143c7.587 0 12.737 5.3165 12.737 13.0143zm-8.529 0c0-3.4336-1.495-5.8703-4.208-5.8703-2.659 0-4.154 2.4367-4.154 5.8703s1.495 5.8149 4.154 5.8149c2.713 0 4.208-2.3813 4.208-5.8149zm28.082-12.5713v8.3624c-1.052-.5538-2.215-.7753-3.6-.7753-2.381 0-3.987 1.0522-4.43 2.8244v14.6203h-8.695v-24.921h8.695v2.2152c1.218-1.6614 3.157-2.769 5.649-2.769 1.107 0 1.993.2215 2.381.443z" fill="#d30001"
|
|
93
|
+
article
|
|
94
|
+
p
|
|
95
|
+
strong
|
|
96
|
+
| We're sorry, but something went wrong.
|
|
97
|
+
br
|
|
98
|
+
| You've run into an unexpected problem please try again later.
|
|
99
|
+
br
|
|
100
|
+
| If the problem persist contact our support department with the following reference code:
|
|
101
|
+
b = request.uuid.split('-').first
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
li.relative.flex.gap-x-4
|
|
2
|
+
.absolute.left-0.top-0.flex.w-6.justify-center.-bottom-6
|
|
3
|
+
.w-px.bg-gray-200
|
|
4
|
+
.relative.flex.h-6.w-6.flex-none.items-center.justify-center.bg-white
|
|
5
|
+
- if trace_element[:file].starts_with?("app")
|
|
6
|
+
.ml-1.h-6.w-6.text-primary-600
|
|
7
|
+
i.fas.fa-circle-exclamation
|
|
8
|
+
- else
|
|
9
|
+
.h-1.5.w-1.5.rounded-full.bg-gray-100.ring-1.ring-gray-300
|
|
10
|
+
|
|
11
|
+
p.flex-auto.py-1.text-xs.leading-5.text-gray-500
|
|
12
|
+
span.font-medium.text-gray-900
|
|
13
|
+
= trace_element[:name]
|
|
14
|
+
time.flex-none.py-0.5.text-xs.leading-5.text-gray-500[datetime="2023-01-23T10:32"]
|
|
15
|
+
= "#{trace_element[:file]}:#{trace_element[:line]}"
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
= sts.card :exceptio_exceptions, title: t('.exceptions'), icon: 'fad fa-triangle-exclamation', content_padding: false do |card|
|
|
2
|
+
- card.with_action
|
|
3
|
+
= link_to(delete_all_exceptions_path, class: 'button bg-red-300', data: { turbo_confirm: 'Are you sure?', turbo_method: :post })
|
|
4
|
+
i.fal.fa-trash
|
|
5
|
+
= sts.table :exceptio_exceptions
|