Opened 12 years ago
Closed 9 years ago
#21931 closed enhancement (fixed)
White screen of death if theme can't be found
Reported by: | ericlewis | Owned by: | |
---|---|---|---|
Milestone: | 4.5 | Priority: | normal |
Severity: | normal | Version: | |
Component: | Themes | Keywords: | |
Focuses: | Cc: |
Description
If the current theme can't be found or is renamed, the front-end of the site will white screen. This is developer error, as when WP_USE_THEMES is true, the template loader should always have a template to load (as far as I understand).
It's rare, but I come across it every once in a while in developing. It might be nice to have a wp_die() if a proper template can't be found in template-loader.
Proof of concept:
if ( $template = apply_filters( 'template_include', $template ) ) include( $template ); else wp_die("Whoops! Looks like you're missing a theme.");
Attachments (11)
Change History (55)
#4
@
12 years ago
- Resolution set to duplicate
- Status changed from new to closed
Duplicate of #11282.
#5
@
12 years ago
- Resolution duplicate deleted
- Status changed from closed to reopened
Related, but not exactly a duplicate.
#6
follow-up:
↓ 7
@
12 years ago
I've also run into this. Should be careful with the error message, since it can show up on live sites in certain circumstances.
#7
in reply to:
↑ 6
@
12 years ago
Replying to scribu:
Should be careful with the error message, since it can show up on live sites in certain circumstances.
Can you expand on that? I can't imagine the circumstance where $template is expected to be empty.
#8
follow-up:
↓ 14
@
12 years ago
I remember I screwed up a deploy once and the theme was renamed. Since I had deleted the twentyeleven theme, I got a WSOD. With this bug, I would get a message instead.
What I'm saying is that the error message shouldn't assume that it will only be seen by developers.
#9
follow-up:
↓ 10
@
12 years ago
what about "Looks like the website is having theme trouble, please notify the site owner" or something to that effect?
#10
in reply to:
↑ 9
@
12 years ago
After chatting with Nacin in IRC a bit, some thought has to be put in here in regard to the ambiguity of the problem, and the ambiguity of the audience. This situation may arise from not just the themes folder missing, it may be a filesystem error, or come from another unknown cause. Therefore, our presentation of the error should respect this fact, and not send developers with possibly misleading debug information.
#11
@
12 years ago
It's nearly the same thing, but not quite; as the developer, you can at least know that WP was loaded.
And if there's a hook available, you can write a plugin that outputs a more useful message or logs it somewhere.
#12
@
12 years ago
Could we do something along the lines of what wp_dashboard_right_now()
does?
http://core.trac.wordpress.org/browser/tags/3.4.2/wp-admin/includes/dashboard.php#L365
If the current theme is not found, 21931.2.diff shows "The theme directory does not exist".
Related #21670 (for more exact message in the admin).
#13
follow-up:
↓ 15
@
12 years ago
The thing about using Right Now in the dashboard to deliver messages is that it can be turned off. Perhaps there is a problem with that as well. Either not allow right now to be turned off or move error messages above the separate content blocks?
#14
in reply to:
↑ 8
@
12 years ago
Replying to scribu:
What I'm saying is that the error message shouldn't assume that it will only be seen by developers.
Let's make the message capability-dependant then.
if ( current_user_can( 'switch_themes' ) ) $message = __( 'You just broke everything!' ); else $message = __( 'Everything is fine and we will be back shortly.' ); wp_die( $message );
#15
in reply to:
↑ 13
;
follow-up:
↓ 16
@
12 years ago
Replying to MikeHansenMe:
The thing about using Right Now in the dashboard to deliver messages is that it can be turned off.
The idea behind 21931.2.diff was to display a similar message on the front end.
#16
in reply to:
↑ 15
@
12 years ago
Replying to SergeyBiryukov:
Replying to MikeHansenMe:
The thing about using Right Now in the dashboard to deliver messages is that it can be turned off.
The idea behind 21931.2.diff was to display a similar message on the front end.
I thought you were suggesting a user message in the front and developer error in the admin. I do think giving the error on the front end is a good idea because like I said, the Right Now area in the admin can be turned off. I think that may be a problem of it's own though.
This ticket was mentioned in IRC in #wordpress-dev by tierra. View the logs.
11 years ago
This ticket was mentioned in Slack in #core by sergey. View the logs.
9 years ago
#24
@
9 years ago
- Milestone changed from Awaiting Review to Future Release
+1 to showing different messages based on user capability.
The WSOD still trips me up when I come across it. The first few times it happened, I remember losing an hour trying to figure out why my frontend didn't load.
+100 to showing a message when the theme can't be found.
#25
@
9 years ago
- Keywords has-patch added; 2nd-opinion ux-error-recovery removed
- Milestone changed from Future Release to 4.5
I think we should do something along the lines of @SergeyBiryukov's suggestion, see attachment:21931.3.diff. which outputs the message The theme directory "{{ theme_directory_name }}" does not exist.
What's wrong with a site visitor seeing this message? Visitors can see the Error establishing a database connection
message, this seems in the same vein. A WP site needs a DB connection, a WP site needs a theme. Fail early, fail explicitly.
@nacin, @SergeyBiryukov — thoughts?
#26
@
9 years ago
This check seems a bit out of place in wp_templating_constants()
, and I can't remember why I put it there :)
21931.4.diff moves it to template-loader.php
, as per the initial suggestion and @MikeHansenMe's first patch.
#27
follow-up:
↓ 28
@
9 years ago
I don't hate 21931.4.diff, but I'm not sold on showing this to anonymous users. Minor code thing: a WP_Error
object can be passed directly to wp_die()
.
Way back when (according to lore), WP used to actively switch to the default theme on the frontend when the theme was broken. In some situations (network-based filesystem, perhaps? — I assume an I/O glitch), this would cause a perfectly normal site to suddenly switch to the default theme. This now only happens in the admin in validate_current_theme()
. Just providing some additional context, which may help inform whether cap checks are necessary here.
One other question to think about: under what circumstances would this else
block be hit? Are we unnecessarily calling wp_get_theme()
(a filesystem hit) in a common situation where we shouldn't?
#28
in reply to:
↑ 27
@
9 years ago
Replying to nacin:
I don't hate 21931.4.diff, but I'm not sold on showing this to anonymous users. Minor code thing: a
WP_Error
object can be passed directly towp_die()
.
Updated in attachment:21931.5.diff, let's show this to logged-in users.
Replying to nacin:
One other question to think about: under what circumstances would this
else
block be hit? Are we unnecessarily callingwp_get_theme()
(a filesystem hit) in a common situation where we shouldn't?
This should only be hit if a theme template is intended to be loaded as far as I can imagine.
#29
@
9 years ago
In attachmnet:21931.6.diff, use `elseif`.
#31
follow-up:
↓ 33
@
9 years ago
What's the reasoning behind only checking is_user_logged_in()
- this doesn't really prove anything about the user being privileged to see anything special. For example, you can be a user without any capabilities whatsoever. IMO is_user_logged_in()
shouldn't be used to indicate anything to do with privilege, we should use current_user_can( 'manage_themes' )
or something similar. If there's no need for any permissions to view this, then is_user_logged_in
seems arbitrary.
#33
in reply to:
↑ 31
@
9 years ago
Replying to joehoyle:
What's the reasoning behind only checking
is_user_logged_in()
- this doesn't really prove anything about the user being privileged to see anything special. For example, you can be a user without any capabilities whatsoever. IMOis_user_logged_in()
shouldn't be used to indicate anything to do with privilege, we should usecurrent_user_can( 'manage_themes' )
or something similar. If there's no need for any permissions to view this, thenis_user_logged_in
seems arbitrary.
That's a good point. Added that cap check in attachment:21931.7.diff.
#36
follow-up:
↓ 37
@
9 years ago
- Keywords has-patch removed
Why install_themes
instead of switch_themes
?
#37
in reply to:
↑ 36
@
9 years ago
Replying to johnbillion:
Why
install_themes
instead ofswitch_themes
?
I was thinking in the worst-case scenario where all themes have been deleted, it will require a user with install_themes
to fix the problem. What do you think?
#38
@
9 years ago
I feel a more basic switch_themes
would be more appropriate if anything here.
Keep multisite in mind as a use-case, where a site admin would rarely have the ability to install themes.
#39
follow-up:
↓ 43
@
9 years ago
- Keywords 2nd-opinion added
I use this filter:
<?php add_filter('template_include', function(){ return locate_template('test.php'); });
And I have white page. I think that should be this if:
<?php if ( $template = apply_filters( 'template_include', $template ) ) { include( $template ); } elseif ( current_user_can( 'install_themes' ) ) { $theme = wp_get_theme(); if ( $theme->errors() ) { wp_die( $theme->errors() ); } else { wp_die( __( 'Template is missing.' ) ); } }
But theme->erros return error if not exists index.php file so better patch is:
<?php if ( $template = apply_filters( 'template_include', $template ) ) { include( $template ); } elseif ( current_user_can( 'install_themes' ) ) { wp_die( __( 'Template is missing.' ) ); }
#43
in reply to:
↑ 39
@
9 years ago
- Keywords dev-feedback 2nd-opinion removed
Replying to sebastian.pisula:
But theme->erros return error if not exists index.php file so better patch is:
<?php if ( $template = apply_filters( 'template_include', $template ) ) { include( $template ); } elseif ( current_user_can( 'install_themes' ) ) { wp_die( __( 'Template is missing.' ) ); }
Thanks for the suggestion here @sebastian.pisula!
This approach is more prone to break things. I could imagine plugins purposefully filtering template_include
to a falsy value to, say, output some JSON (or who knows what else). Of course this is not what template_include is intended for, but in support of backwards compatibility, we should respect this functionality by displaying an error only if there are issues with the theme, which is an exceptional problem for the template loader.
I think this is a good idea as most users would not know where to begin looking if they experienced a white screen.