New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Returning NULL to default_content filter causes fatal error #11176

Closed
wpmark opened this Issue Oct 28, 2018 · 6 comments

Comments

Projects
None yet
7 participants
@wpmark

wpmark commented Oct 28, 2018

Describe the bug
When using a function hooked into the default_content filter, to display default content in the WordPress editor, if the function returns NULL rather than the original content, a fatal error is thrown below:

Fatal error: Uncaught Error: Call to undefined method WP_REST_Themes_Controller::get_fields_for_response() in /srv/www/wordpress-develop/public_html/build/wp-content/plugins/gutenberg/lib/class-wp-rest-themes-controller.php:106 Stack trace: #0 /srv/www/wordpress-develop/public_html/build/wp-content/plugins/gutenberg/lib/class-wp-rest-themes-controller.php(83): WP_REST_Themes_Controller->prepare_item_for_response(Object(WP_Theme), Object(WP_REST_Request)) #1 /srv/www/wordpress-develop/public_html/build/wp-includes/rest-api/class-wp-rest-server.php(943): WP_REST_Themes_Controller->get_items(Object(WP_REST_Request)) #2 /srv/www/wordpress-develop/public_html/build/wp-includes/rest-api.php(390): WP_REST_Server->dispatch(Object(WP_REST_Request)) #3 /srv/www/wordpress-develop/public_html/build/wp-content/plugins/gutenberg/lib/client-assets.php(862): rest_do_request(Object(WP_REST_Request)) #4 [internal function]: gutenberg_preload_api_request(Array, '/wp/v2/themes?s...') #5 /srv/www/wordpress-develop/public_html/build/wp-content in /srv/www/wordpress-develop/public_html/build/wp-content/plugins/gutenberg/lib/class-wp-rest-themes-controller.php on line 106

This is related to the following pull request which was merged.
#10362

To Reproduce

Add the following code, perhaps as a mu-plugin:

add_filter( 'default_content', '__return_null' );

In the WordPress admin areas, click on Posts, then click "add new".

Expected behavior
Without Gutenberg active the default content is empty.

Desktop (please complete the following information):

  • OS: MacOS 10.14
  • Browser: Chrome v69.0.3497.100

Additional context
This is using Gutenberg version 4.1.1

@TimothyBJacobs

This comment has been minimized.

Contributor

TimothyBJacobs commented Oct 28, 2018

What version of WordPress are you using?

@georgestephanis

This comment has been minimized.

georgestephanis commented Oct 28, 2018

Are you actually using backticks in your code for the filter name?

@wpmark

This comment has been minimized.

wpmark commented Oct 28, 2018

Using WordPress 4.9.8 but also tested with WordPress beta 5.0. No the backticks are not in my code, error in pasting the code here.

@salcode

This comment has been minimized.

salcode commented Oct 28, 2018

Confirmed

Running WordPress core 5.0-beta1-43832 on my local test installation (http://gutenberg.test).

I've added the following code in wp-content/mu-plugins/gute-issue-11176.php

add_filter( 'default_content', '__return_null' );

Pre-Gutenberg Behavior

With the Classic Editor plugin installed and activated going to the URL for a new post (e.g. http://gutenberg.test/wp-admin/post-new.php) results in empty content in the editor.

Gutenberg Behavior

Disabling the Classic Editor plugin and going to the URL for a new post (e.g. http://gutenberg.test/wp-admin/post-new.php) results in a blank screen.

Note: When viewing the source on the blank screen (view-source:http://gutenberg.test/wp-admin/post-new.php) you can see markup has been loaded but nothing is rendered.

There are no errors in the PHP error log.

Chrome Browser Console Error Message
react-dom.min.js?ver=5.0-beta1-43832:99 TypeError: Cannot read property 'length' of null
    at b (block-serialization-default-parser.min.js?ver=5.0-beta1-43832:1)
    at p (block-serialization-default-parser.min.js?ver=5.0-beta1-43832:1)
    at s (block-serialization-default-parser.min.js?ver=5.0-beta1-43832:1)
    at blocks.min.js?ver=5.0-beta1-43832:2
    at Array.SETUP_EDITOR (editor.min.js?ver=5.0-beta1-43832:55)
    at Object.dispatch (editor.min.js?ver=5.0-beta1-43832:12)
    at Object.setupEditor (data.min.js?ver=5.0-beta1-43832:1)
    at n.value (data.min.js?ver=5.0-beta1-43832:1)
    at new t (editor.min.js?ver=5.0-beta1-43832:55)
    at sd (react-dom.min.js?ver=5.0-beta1-43832:83)
xf @ react-dom.min.js?ver=5.0-beta1-43832:99
c.callback @ react-dom.min.js?ver=5.0-beta1-43832:105
ef @ react-dom.min.js?ver=5.0-beta1-43832:63
df @ react-dom.min.js?ver=5.0-beta1-43832:63
qc @ react-dom.min.js?ver=5.0-beta1-43832:136
jc @ react-dom.min.js?ver=5.0-beta1-43832:127
aa @ react-dom.min.js?ver=5.0-beta1-43832:126
ta @ react-dom.min.js?ver=5.0-beta1-43832:124
enqueueSetState @ react-dom.min.js?ver=5.0-beta1-43832:182
p.setState @ react.min.js?ver=5.0-beta1-43832:19
(anonymous) @ data.min.js?ver=5.0-beta1-43832:1
(anonymous) @ data.min.js?ver=5.0-beta1-43832:1
(anonymous) @ data.min.js?ver=5.0-beta1-43832:1
v @ data.min.js?ver=5.0-beta1-43832:1
(anonymous) @ data.min.js?ver=5.0-beta1-43832:1
(anonymous) @ data.min.js?ver=5.0-beta1-43832:1
(anonymous) @ redux-routine.min.js?ver=5.0-beta1-43832:1
dispatch @ data.min.js?ver=5.0-beta1-43832:1
(anonymous) @ redux-routine.min.js?ver=5.0-beta1-43832:1
(anonymous) @ redux-routine.min.js?ver=5.0-beta1-43832:1
r @ redux-routine.min.js?ver=5.0-beta1-43832:1
(anonymous) @ redux-routine.min.js?ver=5.0-beta1-43832:1
Promise.then (async)
(anonymous) @ redux-routine.min.js?ver=5.0-beta1-43832:1
(anonymous) @ redux-routine.min.js?ver=5.0-beta1-43832:1
r @ redux-routine.min.js?ver=5.0-beta1-43832:1
(anonymous) @ redux-routine.min.js?ver=5.0-beta1-43832:1
n.any @ redux-routine.min.js?ver=5.0-beta1-43832:1
(anonymous) @ redux-routine.min.js?ver=5.0-beta1-43832:1
r @ redux-routine.min.js?ver=5.0-beta1-43832:1
(anonymous) @ redux-routine.min.js?ver=5.0-beta1-43832:1
n.any @ redux-routine.min.js?ver=5.0-beta1-43832:1
(anonymous) @ redux-routine.min.js?ver=5.0-beta1-43832:1
r @ redux-routine.min.js?ver=5.0-beta1-43832:1
(anonymous) @ redux-routine.min.js?ver=5.0-beta1-43832:1
(anonymous) @ redux-routine.min.js?ver=5.0-beta1-43832:1
r @ redux-routine.min.js?ver=5.0-beta1-43832:1
(anonymous) @ redux-routine.min.js?ver=5.0-beta1-43832:1
n.any @ redux-routine.min.js?ver=5.0-beta1-43832:1
(anonymous) @ redux-routine.min.js?ver=5.0-beta1-43832:1
r @ redux-routine.min.js?ver=5.0-beta1-43832:1
(anonymous) @ redux-routine.min.js?ver=5.0-beta1-43832:1
Promise.then (async)
(anonymous) @ redux-routine.min.js?ver=5.0-beta1-43832:1
(anonymous) @ redux-routine.min.js?ver=5.0-beta1-43832:1
r @ redux-routine.min.js?ver=5.0-beta1-43832:1
(anonymous) @ redux-routine.min.js?ver=5.0-beta1-43832:1
(anonymous) @ redux-routine.min.js?ver=5.0-beta1-43832:1
t @ redux-routine.min.js?ver=5.0-beta1-43832:1
n.iterator @ redux-routine.min.js?ver=5.0-beta1-43832:1
(anonymous) @ redux-routine.min.js?ver=5.0-beta1-43832:1
r @ redux-routine.min.js?ver=5.0-beta1-43832:1
(anonymous) @ redux-routine.min.js?ver=5.0-beta1-43832:1
n.any @ redux-routine.min.js?ver=5.0-beta1-43832:1
(anonymous) @ redux-routine.min.js?ver=5.0-beta1-43832:1
r @ redux-routine.min.js?ver=5.0-beta1-43832:1
(anonymous) @ redux-routine.min.js?ver=5.0-beta1-43832:1
(anonymous) @ redux-routine.min.js?ver=5.0-beta1-43832:1
r @ redux-routine.min.js?ver=5.0-beta1-43832:1
(anonymous) @ redux-routine.min.js?ver=5.0-beta1-43832:1
(anonymous) @ redux-routine.min.js?ver=5.0-beta1-43832:1
t @ redux-routine.min.js?ver=5.0-beta1-43832:1
n.iterator @ redux-routine.min.js?ver=5.0-beta1-43832:1
(anonymous) @ redux-routine.min.js?ver=5.0-beta1-43832:1
r @ redux-routine.min.js?ver=5.0-beta1-43832:1
(anonymous) @ redux-routine.min.js?ver=5.0-beta1-43832:1
(anonymous) @ redux-routine.min.js?ver=5.0-beta1-43832:1
t @ redux-routine.min.js?ver=5.0-beta1-43832:1
(anonymous) @ redux-routine.min.js?ver=5.0-beta1-43832:1
(anonymous) @ redux-routine.min.js?ver=5.0-beta1-43832:1
(anonymous) @ redux-routine.min.js?ver=5.0-beta1-43832:1
(anonymous) @ data.min.js?ver=5.0-beta1-43832:1
tryCatch @ wp-polyfill-ecmascript.min.js?ver=5.0-beta1-43832:3
invoke @ wp-polyfill-ecmascript.min.js?ver=5.0-beta1-43832:3
t.(anonymous function) @ wp-polyfill-ecmascript.min.js?ver=5.0-beta1-43832:3
n @ data.min.js?ver=5.0-beta1-43832:1
c @ data.min.js?ver=5.0-beta1-43832:1
(anonymous) @ data.min.js?ver=5.0-beta1-43832:1
(anonymous) @ data.min.js?ver=5.0-beta1-43832:1
(anonymous) @ data.min.js?ver=5.0-beta1-43832:1
(anonymous) @ data.min.js?ver=5.0-beta1-43832:1
tryCatch @ wp-polyfill-ecmascript.min.js?ver=5.0-beta1-43832:3
invoke @ wp-polyfill-ecmascript.min.js?ver=5.0-beta1-43832:3
t.(anonymous function) @ wp-polyfill-ecmascript.min.js?ver=5.0-beta1-43832:3
n @ data.min.js?ver=5.0-beta1-43832:1
c @ data.min.js?ver=5.0-beta1-43832:1
(anonymous) @ data.min.js?ver=5.0-beta1-43832:1
(anonymous) @ data.min.js?ver=5.0-beta1-43832:1
h @ data.min.js?ver=5.0-beta1-43832:1
(anonymous) @ data.min.js?ver=5.0-beta1-43832:1
(anonymous) @ data.min.js?ver=5.0-beta1-43832:1
(anonymous) @ edit-post.min.js?ver=5.0-beta1-43832:12
n @ data.min.js?ver=5.0-beta1-43832:1
r @ data.min.js?ver=5.0-beta1-43832:1
sd @ react-dom.min.js?ver=5.0-beta1-43832:83
Vg @ react-dom.min.js?ver=5.0-beta1-43832:93
Kf @ react-dom.min.js?ver=5.0-beta1-43832:118
Lf @ react-dom.min.js?ver=5.0-beta1-43832:118
jc @ react-dom.min.js?ver=5.0-beta1-43832:127
aa @ react-dom.min.js?ver=5.0-beta1-43832:126
ta @ react-dom.min.js?ver=5.0-beta1-43832:124
Sf @ react-dom.min.js?ver=5.0-beta1-43832:140
Cd @ react-dom.min.js?ver=5.0-beta1-43832:140
Ta.render @ react-dom.min.js?ver=5.0-beta1-43832:190
(anonymous) @ react-dom.min.js?ver=5.0-beta1-43832:144
Qf @ react-dom.min.js?ver=5.0-beta1-43832:138
sc @ react-dom.min.js?ver=5.0-beta1-43832:143
render @ react-dom.min.js?ver=5.0-beta1-43832:192
Yn @ edit-post.min.js?ver=5.0-beta1-43832:12
(anonymous) @ post-new.php:1662
data.min.js?ver=5.0-beta1-43832:1 Uncaught (in promise) TypeError: Cannot read property 'length' of null
    at b (block-serialization-default-parser.min.js?ver=5.0-beta1-43832:1)
    at p (block-serialization-default-parser.min.js?ver=5.0-beta1-43832:1)
    at s (block-serialization-default-parser.min.js?ver=5.0-beta1-43832:1)
    at blocks.min.js?ver=5.0-beta1-43832:2
    at Array.SETUP_EDITOR (editor.min.js?ver=5.0-beta1-43832:55)
    at Object.dispatch (editor.min.js?ver=5.0-beta1-43832:12)
    at Object.setupEditor (data.min.js?ver=5.0-beta1-43832:1)
    at n.value (data.min.js?ver=5.0-beta1-43832:1)
    at new t (editor.min.js?ver=5.0-beta1-43832:55)
    at sd (react-dom.min.js?ver=5.0-beta1-43832:83)

When the default_content filter returning null is removed, the page loads properly.

Related Note

Using the default_content filter with a string, e.g.

add_filter( 'default_content', function() { return 'This is a <strong>test message</strong>'; } );

works without problem. The problem only occurs when null is returned.

@dd32

This comment has been minimized.

Member

dd32 commented Oct 31, 2018

Fatal error: Uncaught Error: Call to undefined method WP_REST_Themes_Controller

That seems completely unrelated to the issue at hand.


Looking into this, I'm not sure this is necessarily something that should be fixed within Gutenberg.

The problem is caused by Gutenberg expecting a string on initialisation, but being passed null, not a problem in PHP, but an issue in Javascript with how Gutenberg/React operates.

I've opened a core ticket for this, to ensure that the default $post object actually has strings in the fields that it's reasonable to assume are strings.
https://core.trac.wordpress.org/ticket/45236

@danielbachhuber

This comment has been minimized.

Member

danielbachhuber commented Oct 31, 2018

Closing in favor of the core ticket.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment