Add Error tracking models
What does this MR do?
This MR is first in series to implement error tracking functionality inside GitLab. Issue #329596 (closed).
This MR introduces 2 models:
-
ErrorTracking::Error
- to store errors. -
ErrorTracking::ErrorEvent
- to store each event when the error is occured.
Every time the error is raised in client application, we will receive a request with error event information. We will insert 1 row of ErrorTracking::ErrorEvent
and insert or update 1 row of ErrorTracking::Error
.
From a user perspective
User will browse a list of Error
in the project. Based on first_seen_at
, last_seen_at
and count of ErrorEvent
per Error
a user can decide on fixing the error. The payload
from ErrorEvent
provides a stacktrace and other important information to locate the source and the cause of error.
Migrations
UP
Click to expand
== 20210623133635 CreateErrorTrackingErrors: migrating ========================
-- create_table(:error_tracking_errors, {})
-- quote_column_name(:name)
-> 0.0000s
-- quote_column_name(:description)
-> 0.0000s
-- quote_column_name(:actor)
-> 0.0000s
-- quote_column_name(:platform)
-> 0.0000s
-> 0.0077s
-- quote_table_name("check_18a758e537")
-> 0.0000s
-- quote_table_name("check_c739788b12")
-> 0.0000s
-- quote_table_name("check_b5cb4d3888")
-> 0.0000s
-- quote_table_name("check_fe99886883")
-> 0.0000s
-- quote_table_name(:error_tracking_errors)
-> 0.0000s
-- execute("ALTER TABLE \"error_tracking_errors\"\nADD CONSTRAINT \"check_18a758e537\" CHECK (char_length(\"name\") <= 255),\nADD CONSTRAINT \"check_c739788b12\" CHECK (char_length(\"description\") <= 1024),\nADD CONSTRAINT \"check_b5cb4d3888\" CHECK (char_length(\"actor\") <= 255),\nADD CONSTRAINT \"check_fe99886883\" CHECK (char_length(\"platform\") <= 255)\n")
-> 0.0009s
== 20210623133635 CreateErrorTrackingErrors: migrated (0.0128s) ===============
== 20210625094554 CreateErrorTrackingErrorEvents: migrating ===================
-- create_table(:error_tracking_error_events, {})
-- quote_column_name(:description)
-> 0.0000s
-- quote_column_name(:environment)
-> 0.0000s
-- quote_column_name(:level)
-> 0.0000s
-> 0.0042s
-- quote_table_name("check_92ecc3077b")
-> 0.0000s
-- quote_table_name("check_f4b52474ad")
-> 0.0000s
-- quote_table_name("check_c67d5b8007")
-> 0.0000s
-- quote_table_name(:error_tracking_error_events)
-> 0.0000s
-- execute("ALTER TABLE \"error_tracking_error_events\"\nADD CONSTRAINT \"check_92ecc3077b\" CHECK (char_length(\"description\") <= 255),\nADD CONSTRAINT \"check_f4b52474ad\" CHECK (char_length(\"environment\") <= 255),\nADD CONSTRAINT \"check_c67d5b8007\" CHECK (char_length(\"level\") <= 255)\n")
-> 0.0007s
== 20210625094554 CreateErrorTrackingErrorEvents: migrated (0.0078s) ==========
Down
Click to expand
== 20210625094554 CreateErrorTrackingErrorEvents: reverting ===================
-- drop_table(:error_tracking_error_events)
-> 0.0022s
== 20210625094554 CreateErrorTrackingErrorEvents: reverted (0.0023s) ==========
== 20210623133635 CreateErrorTrackingErrors: reverting ========================
-- drop_table(:error_tracking_errors)
-> 0.0025s
== 20210623133635 CreateErrorTrackingErrors: reverted (0.0026s) ===============
Data sample
Example of data that will be stored in JSONB payload. Current expected size is in 10...40KB range. The majority of data is in stacktrace
object. We can truncate some data there if necessary. Or even extract stacktrace
into separate Rails model.
Click to expand
{
"event_id":"85e5e06034a24090bb2d1cfd7a4cba86",
"level":"error",
"timestamp":"2021-06-23T10:25:00Z",
"release":"ad10ffb",
"environment":"development",
"server_name":"dz-laptop.local",
"message":"",
"tags":{
"request_id":"a7dec25c-988d-4f71-8640-afd07db549f1"
},
"contexts":{
"os":{
"name":"Darwin",
"version":"Darwin Kernel Version 20.5.0: Sat May 8 05:10:33 PDT 2021; root:xnu-7195.121.3~9/RELEASE_X86_64",
"build":"20.5.0",
"kernel_version":"Darwin Kernel Version 20.5.0: Sat May 8 05:10:33 PDT 2021; root:xnu-7195.121.3~9/RELEASE_X86_64"
},
"runtime":{
"name":"ruby",
"version":"ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-darwin19]"
},
"trace":{
"trace_id":"34db6833ee8f4e178d076c2b6ac56229",
"span_id":"c4f70f111e78a9bb",
"parent_span_id":null,
"description":null,
"op":"rails.request",
"status":null
}
},
"breadcrumbs":{
"values":[
{
"category":"start_processing.action_controller",
"data":{
"controller":"PostsController",
"action":"error2",
"params":{
"controller":"posts",
"action":"error2"
},
"format":"html",
"method":"GET",
"path":"/posts/error2",
"start_timestamp":1624443900.243959
},
"level":null,
"message":"",
"timestamp":1624443900,
"type":null
},
{
"category":"process_action.action_controller",
"data":{
"controller":"PostsController",
"action":"error2",
"params":{
"controller":"posts",
"action":"error2"
},
"format":"html",
"method":"GET",
"path":"/posts/error2",
"start_timestamp":1624443900.2440488,
"view_runtime":null,
"db_runtime":0
},
"level":null,
"message":"",
"timestamp":1624443900,
"type":null
}
]
},
"transaction":"PostsController#error2",
"platform":"ruby",
"sdk":{
"name":"sentry.ruby.rails",
"version":"4.5.1"
},
"request":{
"url":"http://localhost:4444/posts/error2",
"method":"GET",
"headers":{
"Host":"localhost:4444",
"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:89.0) Gecko/20100101 Firefox/89.0",
"Accept":"text/html, application/xhtml+xml",
"Accept-Language":"en-US,en;q=0.5",
"Accept-Encoding":"gzip, deflate",
"Referer":"http://localhost:4444/",
"Turbolinks-Referrer":"http://localhost:4444/",
"Connection":"keep-alive"
},
"env":{
"SERVER_NAME":"localhost",
"SERVER_PORT":"4444"
}
},
"exception":{
"values":[
{
"type":"ActionView::MissingTemplate",
"value":"Missing template posts/error2, application/error2 with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby, :coffee, :jbuilder]}. Searched in:\n * \"/Users/dzaporozhets/Projects/creator-pairing/blog-no-auth/app/views\"\n",
"module":"ActionView",
"thread_id":70292510053520,
"stacktrace":{
"frames":[
{
"project_root":"/Users/dzaporozhets/Projects/creator-pairing/blog-no-auth",
"abs_path":"/Users/dzaporozhets/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/puma-3.12.6/lib/puma/thread_pool.rb",
"function":"block in spawn_thread",
"lineno":135,
"in_app":false,
"filename":"puma/thread_pool.rb",
"pre_context":[
" end\n",
"\n",
" begin\n"
],
"context_line":" block.call(work, *extra)\n",
"post_context":[
" rescue Exception => e\n",
" STDERR.puts \"Error reached top of thread-pool: #{e.message} (#{e.class})\"\n",
" end\n"
]
},
{
"project_root":"/Users/dzaporozhets/Projects/creator-pairing/blog-no-auth",
"abs_path":"/Users/dzaporozhets/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/puma-3.12.6/lib/puma/server.rb",
"function":"block in run",
"lineno":334,
"in_app":false,
"filename":"puma/server.rb",
"pre_context":[
" client.close\n",
" else\n",
" if process_now\n"
],
"context_line":" process_client client, buffer\n",
"post_context":[
" else\n",
" client.set_timeout @first_data_timeout\n",
" @reactor.add client\n"
]
},
{
"project_root":"/Users/dzaporozhets/Projects/creator-pairing/blog-no-auth",
"abs_path":"/Users/dzaporozhets/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/puma-3.12.6/lib/puma/server.rb",
"function":"process_client",
"lineno":476,
"in_app":false,
"filename":"puma/server.rb",
"pre_context":[
" requests = 0\n",
"\n",
" while true\n"
],
"context_line":" case handle_request(client, buffer)\n",
"post_context":[
" when false\n",
" return\n",
" when :async\n"
]
},
{
"project_root":"/Users/dzaporozhets/Projects/creator-pairing/blog-no-auth",
"abs_path":"/Users/dzaporozhets/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/puma-3.12.6/lib/puma/server.rb",
"function":"handle_request",
"lineno":706,
"in_app":false,
"filename":"puma/server.rb",
"pre_context":[
"\n",
" begin\n",
" begin\n"
],
"context_line":" status, headers, res_body = @app.call(env)\n",
"post_context":[
"\n",
" return :async if req.hijacked\n",
"\n"
]
},
{
"project_root":"/Users/dzaporozhets/Projects/creator-pairing/blog-no-auth",
"abs_path":"/Users/dzaporozhets/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/puma-3.12.6/lib/puma/configuration.rb",
"function":"call",
"lineno":227,
"in_app":false,
"filename":"puma/configuration.rb",
"pre_context":[
"\n",
" def call(env)\n",
" env[Const::PUMA_CONFIG] = @config\n"
],
"context_line":" @app.call(env)\n",
"post_context":[
" end\n",
" end\n",
"\n"
]
},
{
"project_root":"/Users/dzaporozhets/Projects/creator-pairing/blog-no-auth",
"abs_path":"/Users/dzaporozhets/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/railties-5.2.6/lib/rails/engine.rb",
"function":"call",
"lineno":524,
"in_app":false,
"filename":"rails/engine.rb",
"pre_context":[
" # Define the Rack API for this engine.\n",
" def call(env)\n",
" req = build_request env\n"
],
"context_line":" app.call req.env\n",
"post_context":[
" end\n",
"\n",
" # Defines additional Rack env configuration that is added on each call.\n"
]
},
{
"project_root":"/Users/dzaporozhets/Projects/creator-pairing/blog-no-auth",
"abs_path":"/Users/dzaporozhets/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/rack-2.2.3/lib/rack/sendfile.rb",
"function":"call",
"lineno":110,
"in_app":false,
"filename":"rack/sendfile.rb",
"pre_context":[
" end\n",
"\n",
" def call(env)\n"
],
"context_line":" status, headers, body = @app.call(env)\n",
"post_context":[
" if body.respond_to?(:to_path)\n",
" case type = variation(env)\n",
" when 'X-Accel-Redirect'\n"
]
},
{
"project_root":"/Users/dzaporozhets/Projects/creator-pairing/blog-no-auth",
"abs_path":"/Users/dzaporozhets/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/actionpack-5.2.6/lib/action_dispatch/middleware/static.rb",
"function":"call",
"lineno":127,
"in_app":false,
"filename":"action_dispatch/middleware/static.rb",
"pre_context":[
" end\n",
" end\n",
"\n"
],
"context_line":" @app.call(req.env)\n",
"post_context":[
" end\n",
" end\n",
"end\n"
]
},
{
"project_root":"/Users/dzaporozhets/Projects/creator-pairing/blog-no-auth",
"abs_path":"/Users/dzaporozhets/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/actionpack-5.2.6/lib/action_dispatch/middleware/executor.rb",
"function":"call",
"lineno":14,
"in_app":false,
"filename":"action_dispatch/middleware/executor.rb",
"pre_context":[
" def call(env)\n",
" state = @executor.run!\n",
" begin\n"
],
"context_line":" response = @app.call(env)\n",
"post_context":[
" returned = response << ::Rack::BodyProxy.new(response.pop) { state.complete! }\n",
" ensure\n",
" state.complete! unless returned\n"
]
},
{
"project_root":"/Users/dzaporozhets/Projects/creator-pairing/blog-no-auth",
"abs_path":"/Users/dzaporozhets/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/sentry-ruby-core-4.5.1/lib/sentry/rack/capture_exceptions.rb",
"function":"call",
"lineno":14,
"in_app":false,
"filename":"sentry/rack/capture_exceptions.rb",
"pre_context":[
" # make sure the current thread has a clean hub\n",
" Sentry.clone_hub_to_current_thread\n",
"\n"
],
"context_line":" Sentry.with_scope do |scope|\n",
"post_context":[
" scope.clear_breadcrumbs\n",
" scope.set_transaction_name(env[\"PATH_INFO\"]) if env[\"PATH_INFO\"]\n",
" scope.set_rack_env(env)\n"
]
},
{
"project_root":"/Users/dzaporozhets/Projects/creator-pairing/blog-no-auth",
"abs_path":"/Users/dzaporozhets/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/sentry-ruby-core-4.5.1/lib/sentry-ruby.rb",
"function":"with_scope",
"lineno":167,
"in_app":false,
"filename":"sentry-ruby.rb",
"pre_context":[
" # ```\n",
" #\n",
" def with_scope(&block)\n"
],
"context_line":" get_current_hub&.with_scope(&block)\n",
"post_context":[
" end\n",
"\n",
" # Takes an exception and reports it to Sentry via the currently active hub.\n"
]
},
{
"project_root":"/Users/dzaporozhets/Projects/creator-pairing/blog-no-auth",
"abs_path":"/Users/dzaporozhets/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/sentry-ruby-core-4.5.1/lib/sentry/hub.rb",
"function":"with_scope",
"lineno":56,
"in_app":false,
"filename":"sentry/hub.rb",
"pre_context":[
"\n",
" def with_scope(&block)\n",
" push_scope\n"
],
"context_line":" yield(current_scope)\n",
"post_context":[
" ensure\n",
" pop_scope\n",
" end\n"
]
},
{
"project_root":"/Users/dzaporozhets/Projects/creator-pairing/blog-no-auth",
"abs_path":"/Users/dzaporozhets/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/sentry-ruby-core-4.5.1/lib/sentry/rack/capture_exceptions.rb",
"function":"block in call",
"lineno":23,
"in_app":false,
"filename":"sentry/rack/capture_exceptions.rb",
"pre_context":[
" scope.set_span(transaction) if transaction\n",
"\n",
" begin\n"
],
"context_line":" response = @app.call(env)\n",
"post_context":[
" rescue Sentry::Error\n",
" finish_transaction(transaction, 500)\n",
" raise # Don't capture Sentry errors\n"
]
},
{
"project_root":"/Users/dzaporozhets/Projects/creator-pairing/blog-no-auth",
"abs_path":"/Users/dzaporozhets/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/activesupport-5.2.6/lib/active_support/cache/strategy/local_cache_middleware.rb",
"function":"call",
"lineno":29,
"in_app":false,
"filename":"active_support/cache/strategy/local_cache_middleware.rb",
"pre_context":[
"\n",
" def call(env)\n",
" LocalCacheRegistry.set_cache_for(local_cache_key, LocalStore.new)\n"
],
"context_line":" response = @app.call(env)\n",
"post_context":[
" response[2] = ::Rack::BodyProxy.new(response[2]) do\n",
" LocalCacheRegistry.set_cache_for(local_cache_key, nil)\n",
" end\n"
]
},
{
"project_root":"/Users/dzaporozhets/Projects/creator-pairing/blog-no-auth",
"abs_path":"/Users/dzaporozhets/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/rack-2.2.3/lib/rack/runtime.rb",
"function":"call",
"lineno":22,
"in_app":false,
"filename":"rack/runtime.rb",
"pre_context":[
"\n",
" def call(env)\n",
" start_time = Utils.clock_time\n"
],
"context_line":" status, headers, body = @app.call(env)\n",
"post_context":[
" headers = Utils::HeaderHash[headers]\n",
"\n",
" request_time = Utils.clock_time - start_time\n"
]
},
{
"project_root":"/Users/dzaporozhets/Projects/creator-pairing/blog-no-auth",
"abs_path":"/Users/dzaporozhets/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/rack-2.2.3/lib/rack/method_override.rb",
"function":"call",
"lineno":24,
"in_app":false,
"filename":"rack/method_override.rb",
"pre_context":[
" end\n",
" end\n",
"\n"
],
"context_line":" @app.call(env)\n",
"post_context":[
" end\n",
"\n",
" def method_override(env)\n"
]
},
{
"project_root":"/Users/dzaporozhets/Projects/creator-pairing/blog-no-auth",
"abs_path":"/Users/dzaporozhets/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/actionpack-5.2.6/lib/action_dispatch/middleware/request_id.rb",
"function":"call",
"lineno":27,
"in_app":false,
"filename":"action_dispatch/middleware/request_id.rb",
"pre_context":[
" def call(env)\n",
" req = ActionDispatch::Request.new env\n",
" req.request_id = make_request_id(req.x_request_id)\n"
],
"context_line":" @app.call(env).tap { |_status, headers, _body| headers[X_REQUEST_ID] = req.request_id }\n",
"post_context":[
" end\n",
"\n",
" private\n"
]
},
{
"project_root":"/Users/dzaporozhets/Projects/creator-pairing/blog-no-auth",
"abs_path":"/Users/dzaporozhets/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/actionpack-5.2.6/lib/action_dispatch/middleware/remote_ip.rb",
"function":"call",
"lineno":81,
"in_app":false,
"filename":"action_dispatch/middleware/remote_ip.rb",
"pre_context":[
" def call(env)\n",
" req = ActionDispatch::Request.new env\n",
" req.remote_ip = GetIp.new(req, check_ip, proxies)\n"
],
"context_line":" @app.call(req.env)\n",
"post_context":[
" end\n",
"\n",
" # The GetIp class exists as a way to defer processing of the request data\n"
]
},
{
"project_root":"/Users/dzaporozhets/Projects/creator-pairing/blog-no-auth",
"abs_path":"/Users/dzaporozhets/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/sprockets-rails-3.2.2/lib/sprockets/rails/quiet_assets.rb",
"function":"call",
"lineno":13,
"in_app":false,
"filename":"sprockets/rails/quiet_assets.rb",
"pre_context":[
" if env['PATH_INFO'] =~ @assets_regex\n",
" ::Rails.logger.silence { @app.call(env) }\n",
" else\n"
],
"context_line":" @app.call(env)\n",
"post_context":[
" end\n",
" end\n",
" end\n"
]
},
{
"project_root":"/Users/dzaporozhets/Projects/creator-pairing/blog-no-auth",
"abs_path":"/Users/dzaporozhets/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/railties-5.2.6/lib/rails/rack/logger.rb",
"function":"call",
"lineno":26,
"in_app":false,
"filename":"rails/rack/logger.rb",
"pre_context":[
" request = ActionDispatch::Request.new(env)\n",
"\n",
" if logger.respond_to?(:tagged)\n"
],
"context_line":" logger.tagged(compute_tags(request)) { call_app(request, env) }\n",
"post_context":[
" else\n",
" call_app(request, env)\n",
" end\n"
]
},
{
"project_root":"/Users/dzaporozhets/Projects/creator-pairing/blog-no-auth",
"abs_path":"/Users/dzaporozhets/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/activesupport-5.2.6/lib/active_support/tagged_logging.rb",
"function":"tagged",
"lineno":71,
"in_app":false,
"filename":"active_support/tagged_logging.rb",
"pre_context":[
" delegate :push_tags, :pop_tags, :clear_tags!, to: :formatter\n",
"\n",
" def tagged(*tags)\n"
],
"context_line":" formatter.tagged(*tags) { yield self }\n",
"post_context":[
" end\n",
"\n",
" def flush\n"
]
},
{
"project_root":"/Users/dzaporozhets/Projects/creator-pairing/blog-no-auth",
"abs_path":"/Users/dzaporozhets/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/activesupport-5.2.6/lib/active_support/tagged_logging.rb",
"function":"tagged",
"lineno":28,
"in_app":false,
"filename":"active_support/tagged_logging.rb",
"pre_context":[
"\n",
" def tagged(*tags)\n",
" new_tags = push_tags(*tags)\n"
],
"context_line":" yield self\n",
"post_context":[
" ensure\n",
" pop_tags(new_tags.size)\n",
" end\n"
]
},
{
"project_root":"/Users/dzaporozhets/Projects/creator-pairing/blog-no-auth",
"abs_path":"/Users/dzaporozhets/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/activesupport-5.2.6/lib/active_support/tagged_logging.rb",
"function":"block in tagged",
"lineno":71,
"in_app":false,
"filename":"active_support/tagged_logging.rb",
"pre_context":[
" delegate :push_tags, :pop_tags, :clear_tags!, to: :formatter\n",
"\n",
" def tagged(*tags)\n"
],
"context_line":" formatter.tagged(*tags) { yield self }\n",
"post_context":[
" end\n",
"\n",
" def flush\n"
]
},
{
"project_root":"/Users/dzaporozhets/Projects/creator-pairing/blog-no-auth",
"abs_path":"/Users/dzaporozhets/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/railties-5.2.6/lib/rails/rack/logger.rb",
"function":"block in call",
"lineno":26,
"in_app":false,
"filename":"rails/rack/logger.rb",
"pre_context":[
" request = ActionDispatch::Request.new(env)\n",
"\n",
" if logger.respond_to?(:tagged)\n"
],
"context_line":" logger.tagged(compute_tags(request)) { call_app(request, env) }\n",
"post_context":[
" else\n",
" call_app(request, env)\n",
" end\n"
]
},
{
"project_root":"/Users/dzaporozhets/Projects/creator-pairing/blog-no-auth",
"abs_path":"/Users/dzaporozhets/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/railties-5.2.6/lib/rails/rack/logger.rb",
"function":"call_app",
"lineno":38,
"in_app":false,
"filename":"rails/rack/logger.rb",
"pre_context":[
" instrumenter = ActiveSupport::Notifications.instrumenter\n",
" instrumenter.start \"request.action_dispatch\", request: request\n",
" logger.info { started_request_message(request) }\n"
],
"context_line":" status, headers, body = @app.call(env)\n",
"post_context":[
" body = ::Rack::BodyProxy.new(body) { finish(request) }\n",
" [status, headers, body]\n",
" rescue Exception\n"
]
},
{
"project_root":"/Users/dzaporozhets/Projects/creator-pairing/blog-no-auth",
"abs_path":"/Users/dzaporozhets/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/actionpack-5.2.6/lib/action_dispatch/middleware/show_exceptions.rb",
"function":"call",
"lineno":33,
"in_app":false,
"filename":"action_dispatch/middleware/show_exceptions.rb",
"pre_context":[
"\n",
" def call(env)\n",
" request = ActionDispatch::Request.new env\n"
],
"context_line":" @app.call(env)\n",
"post_context":[
" rescue Exception => exception\n",
" if request.show_exceptions?\n",
" render_exception(request, exception)\n"
]
},
{
"project_root":"/Users/dzaporozhets/Projects/creator-pairing/blog-no-auth",
"abs_path":"/Users/dzaporozhets/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/web-console-3.7.0/lib/web_console/middleware.rb",
"function":"call",
"lineno":20,
"in_app":false,
"filename":"web_console/middleware.rb",
"pre_context":[
" end\n",
"\n",
" def call(env)\n"
],
"context_line":" app_exception = catch :app_exception do\n",
"post_context":[
" request = create_regular_or_whiny_request(env)\n",
" return call_app(env) unless request.from_whitelisted_ip?\n",
"\n"
]
},
{
"project_root":"/Users/dzaporozhets/Projects/creator-pairing/blog-no-auth",
"abs_path":"/Users/dzaporozhets/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/web-console-3.7.0/lib/web_console/middleware.rb",
"function":"catch",
"lineno":20,
"in_app":false,
"filename":"web_console/middleware.rb",
"pre_context":[
" end\n",
"\n",
" def call(env)\n"
],
"context_line":" app_exception = catch :app_exception do\n",
"post_context":[
" request = create_regular_or_whiny_request(env)\n",
" return call_app(env) unless request.from_whitelisted_ip?\n",
"\n"
]
},
{
"project_root":"/Users/dzaporozhets/Projects/creator-pairing/blog-no-auth",
"abs_path":"/Users/dzaporozhets/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/activesupport-5.2.6/lib/active_support/notifications.rb",
"function":"instrument",
"lineno":168,
"in_app":false,
"filename":"active_support/notifications.rb",
"pre_context":[
"\n",
" def instrument(name, payload = {})\n",
" if notifier.listening?(name)\n"
],
"context_line":" instrumenter.instrument(name, payload) { yield payload if block_given? }\n",
"post_context":[
" else\n",
" yield payload if block_given?\n",
" end\n"
]
},
{
"project_root":"/Users/dzaporozhets/Projects/creator-pairing/blog-no-auth",
"abs_path":"/Users/dzaporozhets/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/sentry-rails-4.5.1/lib/sentry/rails/tracing.rb",
"function":"instrument",
"lineno":42,
"in_app":false,
"filename":"sentry/rails/tracing.rb",
"pre_context":[
"\n",
" payload[:start_timestamp] = Time.now.utc.to_f if is_public_event\n",
"\n"
],
"context_line":" super(name, payload, &block)\n",
"post_context":[
" end\n",
" end\n",
" end\n"
]
},
{
"project_root":"/Users/dzaporozhets/Projects/creator-pairing/blog-no-auth",
"abs_path":"/Users/dzaporozhets/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/activesupport-5.2.6/lib/active_support/notifications/instrumenter.rb",
"function":"instrument",
"lineno":23,
"in_app":false,
"filename":"active_support/notifications/instrumenter.rb",
"pre_context":[
" # some of the listeners might have state\n",
" listeners_state = start name, payload\n",
" begin\n"
],
"context_line":" yield payload\n",
"post_context":[
" rescue Exception => e\n",
" payload[:exception] = [e.class.name, e.message]\n",
" payload[:exception_object] = e\n"
]
},
{
"project_root":"/Users/dzaporozhets/Projects/creator-pairing/blog-no-auth",
"abs_path":"/Users/dzaporozhets/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/activesupport-5.2.6/lib/active_support/notifications.rb",
"function":"block in instrument",
"lineno":168,
"in_app":false,
"filename":"active_support/notifications.rb",
"pre_context":[
"\n",
" def instrument(name, payload = {})\n",
" if notifier.listening?(name)\n"
],
"context_line":" instrumenter.instrument(name, payload) { yield payload if block_given? }\n",
"post_context":[
" else\n",
" yield payload if block_given?\n",
" end\n"
]
},
{
"project_root":"/Users/dzaporozhets/Projects/creator-pairing/blog-no-auth",
"abs_path":"/Users/dzaporozhets/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/actionpack-5.2.6/lib/action_controller/metal/instrumentation.rb",
"function":"block in process_action",
"lineno":34,
"in_app":false,
"filename":"action_controller/metal/instrumentation.rb",
"pre_context":[
"\n",
" ActiveSupport::Notifications.instrument(\"process_action.action_controller\", raw_payload) do |payload|\n",
" begin\n"
],
"context_line":" result = super\n",
"post_context":[
" payload[:status] = response.status\n",
" result\n",
" ensure\n"
]
},
{
"project_root":"/Users/dzaporozhets/Projects/creator-pairing/blog-no-auth",
"abs_path":"/Users/dzaporozhets/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/actionpack-5.2.6/lib/action_controller/metal/rescue.rb",
"function":"process_action",
"lineno":22,
"in_app":false,
"filename":"action_controller/metal/rescue.rb",
"pre_context":[
"\n",
" private\n",
" def process_action(*args)\n"
],
"context_line":" super\n",
"post_context":[
" rescue Exception => exception\n",
" request.env[\"action_dispatch.show_detailed_exceptions\"] ||= show_detailed_exceptions?\n",
" rescue_with_handler(exception) || raise\n"
]
},
{
"project_root":"/Users/dzaporozhets/Projects/creator-pairing/blog-no-auth",
"abs_path":"/Users/dzaporozhets/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/actionview-5.2.6/lib/action_view/path_set.rb",
"function":"find",
"lineno":48,
"in_app":false,
"filename":"action_view/path_set.rb",
"pre_context":[
" end\n",
"\n",
" def find(*args)\n"
],
"context_line":" find_all(*args).first || raise(MissingTemplate.new(self, *args))\n",
"post_context":[
" end\n",
"\n",
" def find_file(path, prefixes = [], *args)\n"
]
}
]
}
}
]
}
}
Screenshots (strongly suggested)
No frontend changes
Does this MR meet the acceptance criteria?
Conformity
-
I have included changelog trailers, or none are needed. (Does this MR need a changelog?) - [-] I have added/updated documentation, or it's not needed. (Is documentation required?)
-
I have properly separated EE content from FOSS, or this MR is FOSS only. (Where should EE code go?) -
I have added information for database reviewers in the MR description, or it's not needed. (Does this MR have database related changes?) -
I have self-reviewed this MR per code review guidelines. -
This MR does not harm performance, or I have asked a reviewer to help assess the performance impact. (Merge request performance guidelines) -
I have followed the style guides. -
This change is backwards compatible across updates, or this does not apply.
Availability and Testing
-
I have added/updated tests following the Testing Guide, or it's not needed. (Consider all test levels. See the Test Planning Process.) - [-] I have tested this MR in all supported browsers, or it's not needed.
- [-] I have informed the Infrastructure department of a default or new setting change per definition of done, or it's not needed.
Security
Does this MR contain changes to processing or storing of credentials or tokens, authorization and authentication methods or other items described in the security review guidelines? If not, then delete this Security section.
- [-] Label as security and @ mention
@gitlab-com/gl-security/appsec
- [-] The MR includes necessary changes to maintain consistency between UI, API, email, or other methods
- [-] Security reports checked/validated by a reviewer from the AppSec team