FIX: Ensure error handlers render correctly without preload_json (#17696)

Some errors (e.g. InvalidAccess) are rendered with `include_ember: true`. Booting the ember app requires that the 'preload' data is rendered in the HTML.

If a particular route was configured to `skip_before_action :preload_json`, and then went on to raise an InvalidAccess error, then we'd attempt to render the Ember app without the preload json. This led to a blank screen and a client-side error.

This commit ensures that error pages will fallback to the no_ember view if there is no preload data. It also adds a sanity check in `discourse-bootstrap` so that it's easier for us to identify similar errors in future.
This commit is contained in:
David Taylor 2022-07-27 22:29:13 +01:00 committed by GitHub
parent 7980c41832
commit d3751c70c9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 15 additions and 3 deletions

View File

@ -38,7 +38,12 @@ export default {
preloaded = JSON.parse(preloadedDataElement.dataset.preloaded);
}
Object.keys(preloaded).forEach(function (key) {
const keys = Object.keys(preloaded);
if (keys.length === 0) {
throw "No preload data found in #data-preloaded. Unable to boot Discourse.";
}
keys.forEach(function (key) {
PreloadStore.store(key, JSON.parse(preloaded[key]));
if (setupData.debugPreloadedAppData === "true") {

View File

@ -339,7 +339,7 @@ class ApplicationController < ActionController::Base
return render plain: message, status: status_code
end
with_resolved_locale do
error_page_opts[:layout] = opts[:include_ember] ? 'application' : 'no_ember'
error_page_opts[:layout] = (opts[:include_ember] && @preloaded) ? 'application' : 'no_ember'
render html: build_not_found_page(error_page_opts)
end
end

View File

@ -2000,12 +2000,19 @@ describe PostsController do
expect(response).to be_redirect
end
it "returns a 403 when access is denied" do
it "returns a 403 when access is denied for JSON format" do
post = Fabricate(:private_message_post)
get "/p/#{post.id}.json"
expect(response).to be_forbidden
end
it "returns a 403 when access is denied for HTML format" do
post = Fabricate(:private_message_post)
get "/p/#{post.id}"
expect(response).to be_forbidden
expect(response.body).to have_tag("body.no-ember")
end
it "renders a 404 page" do
get "/p/0"
expect(response.status).to eq(404)