FEATURE: Add site setting to show more detailed 404 errors. (#8014)

If the setting is turned on, then the user will receive information
about the subject: if it was deleted or requires some special access to
a group (only if the group is public). Otherwise, the user will receive
a generic #404 error message. For now, this change affects only the
topics and categories controller.

This commit also tries to refactor some of the code related to error
handling. To make error pages more consistent (design-wise), the actual
error page will be rendered server-side.
This commit is contained in:
Dan Ungureanu
2019-10-08 14:15:08 +03:00
committed by GitHub
parent d2bceff133
commit fdb1d3404c
23 changed files with 769 additions and 660 deletions

View File

@ -79,12 +79,54 @@ class TopicsController < ApplicationController
begin
@topic_view = TopicView.new(params[:id] || params[:topic_id], current_user, opts)
rescue Discourse::NotFound
rescue Discourse::NotFound => ex
if params[:id]
topic = Topic.find_by(slug: params[:id].downcase)
return redirect_to_correct_topic(topic, opts[:post_number]) if topic
end
raise Discourse::NotFound
raise ex
rescue Discourse::NotLoggedIn => ex
if !SiteSetting.detailed_404
raise Discourse::NotFound
else
raise ex
end
rescue Discourse::InvalidAccess => ex
# If the user can't see the topic, clean up notifications for it.
Notification.remove_for(current_user.id, params[:topic_id]) if current_user
deleted = guardian.can_see_topic?(ex.obj, false) ||
(!guardian.can_see_topic?(ex.obj) &&
ex.obj&.access_topic_via_group &&
ex.obj.deleted_at)
if SiteSetting.detailed_404
if deleted
raise Discourse::NotFound.new(
'deleted topic',
custom_message: 'deleted_topic',
status: 410,
check_permalinks: true,
original_path: ex.obj.relative_url
)
elsif !guardian.can_see_topic?(ex.obj) && group = ex.obj&.access_topic_via_group
raise Discourse::InvalidAccess.new(
'not in group',
ex.obj,
custom_message: 'not_in_group.title_topic',
group: group
)
end
raise ex
else
raise Discourse::NotFound.new(
nil,
check_permalinks: deleted,
original_path: ex.obj.relative_url
)
end
end
page = params[:page]
@ -120,27 +162,6 @@ class TopicsController < ApplicationController
end
perform_show_response
rescue Discourse::InvalidAccess => ex
if !guardian.can_see_topic?(ex.obj) && guardian.can_get_access_to_topic?(ex.obj)
return perform_hidden_topic_show_response(ex.obj)
end
if current_user
# If the user can't see the topic, clean up notifications for it.
Notification.remove_for(current_user.id, params[:topic_id])
end
if ex.obj && Topic === ex.obj && guardian.can_see_topic_if_not_deleted?(ex.obj)
raise Discourse::NotFound.new(
"topic was deleted",
status: 410,
check_permalinks: true,
original_path: ex.obj.relative_url
)
end
raise ex
end
def publish
@ -960,19 +981,6 @@ class TopicsController < ApplicationController
end
end
def perform_hidden_topic_show_response(topic)
respond_to do |format|
format.html do
@topic_view = nil
render :show
end
format.json do
render_serialized(topic, HiddenTopicViewSerializer, root: false)
end
end
end
def render_topic_changes(dest_topic)
if dest_topic.present?
render json: { success: true, url: dest_topic.relative_url }