mirror of
https://github.com/discourse/discourse.git
synced 2025-06-01 09:05:53 +08:00
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:
@ -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 }
|
||||
|
Reference in New Issue
Block a user