Commit 88ca1188 authored by Stan Hu's avatar Stan Hu

Merge branch 'add-correlation-id-to-500-page' into 'master'

Show request ID on 500 error page

See merge request gitlab-org/gitlab!77377
parents 7f682a50 724f4c5f
...@@ -68,6 +68,9 @@ module Gitlab ...@@ -68,6 +68,9 @@ module Gitlab
require_dependency Rails.root.join('lib/gitlab/middleware/rack_multipart_tempfile_factory') require_dependency Rails.root.join('lib/gitlab/middleware/rack_multipart_tempfile_factory')
require_dependency Rails.root.join('lib/gitlab/runtime') require_dependency Rails.root.join('lib/gitlab/runtime')
require_dependency Rails.root.join('lib/gitlab/patch/legacy_database_config') require_dependency Rails.root.join('lib/gitlab/patch/legacy_database_config')
require_dependency Rails.root.join('lib/gitlab/exceptions_app')
config.exceptions_app = Gitlab::ExceptionsApp.new(Rails.public_path)
# To be removed in 15.0 # To be removed in 15.0
# This preload is needed to convert legacy `database.yml` # This preload is needed to convert legacy `database.yml`
......
# frozen_string_literal: true
require_relative 'utils/override'
module Gitlab
class ExceptionsApp < ActionDispatch::PublicExceptions
extend ::Gitlab::Utils::Override
REQUEST_ID_PLACEHOLDER = '<!-- REQUEST_ID -->'
REQUEST_ID_PARAGRAPH = '<p>Request ID: <code>%s</code></p>'
override :call
def call(env)
status, headers, body = super
if html_rendered? && body.first&.include?(REQUEST_ID_PLACEHOLDER)
body = [insert_request_id(env, body.first)]
headers['X-GitLab-Custom-Error'] = '1'
end
[status, headers, body]
end
private
override :render_html
def render_html(status)
@html_rendered = true
super
end
def html_rendered?
!!@html_rendered
end
def insert_request_id(env, body)
request_id = ERB::Util.html_escape(ActionDispatch::Request.new(env).request_id)
body.gsub(REQUEST_ID_PLACEHOLDER, REQUEST_ID_PARAGRAPH % [request_id])
end
end
end
...@@ -76,6 +76,7 @@ ...@@ -76,6 +76,7 @@
<div class="container"> <div class="container">
<h3>Whoops, something went wrong on our end.</h3> <h3>Whoops, something went wrong on our end.</h3>
<hr /> <hr />
<!-- REQUEST_ID -->
<p>Try refreshing the page, or going back and attempting the action again.</p> <p>Try refreshing the page, or going back and attempting the action again.</p>
<p>Please contact your GitLab administrator if this problem persists.</p> <p>Please contact your GitLab administrator if this problem persists.</p>
<a href="javascript:history.back()" class="js-go-back go-back">Go back</a> <a href="javascript:history.back()" class="js-go-back go-back">Go back</a>
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::ExceptionsApp, type: :request do
describe '.call' do
let(:exceptions_app) { described_class.new(Rails.public_path) }
let(:app) { ActionDispatch::ShowExceptions.new(error_raiser, exceptions_app) }
before do
@app = app
end
context 'for a 500 error' do
let(:error_raiser) { proc { raise 'an unhandled error' } }
context 'for an HTML request' do
it 'fills in the request ID' do
get '/', env: { 'action_dispatch.request_id' => 'foo' }
expect(response).to have_gitlab_http_status(:internal_server_error)
expect(response).to have_header('X-Gitlab-Custom-Error')
expect(response.body).to include('Request ID: <code>foo</code>')
end
it 'HTML-escapes the request ID' do
get '/', env: { 'action_dispatch.request_id' => '<b>foo</b>' }
expect(response).to have_gitlab_http_status(:internal_server_error)
expect(response).to have_header('X-Gitlab-Custom-Error')
expect(response.body).to include('Request ID: <code>&lt;b&gt;foo&lt;/b&gt;</code>')
end
it 'returns an empty 500 when the 500.html page cannot be found' do
allow(File).to receive(:exist?).and_return(false)
get '/', env: { 'action_dispatch.request_id' => 'foo' }
expect(response).to have_gitlab_http_status(:internal_server_error)
expect(response).not_to have_header('X-Gitlab-Custom-Error')
expect(response.body).to be_empty
end
end
context 'for a JSON request' do
it 'does not include the request ID' do
get '/', env: { 'action_dispatch.request_id' => 'foo' }, as: :json
expect(response).to have_gitlab_http_status(:internal_server_error)
expect(response).not_to have_header('X-Gitlab-Custom-Error')
expect(response.body).not_to include('foo')
end
end
end
context 'for a 404 error' do
let(:error_raiser) { proc { raise AbstractController::ActionNotFound } }
it 'returns a 404 response that does not include the request ID' do
get '/', env: { 'action_dispatch.request_id' => 'foo' }
expect(response).to have_gitlab_http_status(:not_found)
expect(response).not_to have_header('X-Gitlab-Custom-Error')
expect(response.body).not_to include('foo')
end
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment