Viewing output when the “The plugin generated x characters of unexpected output during activation” error is triggered

I’m working on a plugin and having some difficulties getting a new table created. I get the “The plugin generated x characters of unexpected output during activation” error. Is there a way of viewing the actual error? I believe that a redirect is involved in this process, hence the reason I don’t see the actual error output. I have all error reporting and logging on, but still I get nothing.

Related posts

Leave a Reply

3 comments

  1. Interestingly the ability to display errors and output from a plugin on activation seems to be build in to WordPress. If you take a look at wp-admin/plugins.php there’s a case in the $action switch statement that says error_scrape — hinted at in Lars’ answer.

    Looks like this:

    <?php
    // wp-admin/plugins.php
    case 'error_scrape':
        if ( ! current_user_can('activate_plugins') )
            wp_die(__('You do not have sufficient permissions to activate plugins for this site.'));
    
        check_admin_referer('plugin-activation-error_' . $plugin);
    
        $valid = validate_plugin($plugin);
        if ( is_wp_error($valid) )
            wp_die($valid);
    
        if ( ! WP_DEBUG ) {
            error_reporting( E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_ERROR | E_WARNING | E_PARSE | E_USER_ERROR | E_USER_WARNING | E_RECOVERABLE_ERROR );
        }
    
        @ini_set('display_errors', true); //Ensure that Fatal errors are displayed.
        // Go back to "sandbox" scope so we get the same errors as before
        function plugin_sandbox_scrape( $plugin ) {
            include( WP_PLUGIN_DIR . '/' . $plugin );
        }
        plugin_sandbox_scrape( $plugin );
        do_action('activate_' . $plugin);
        exit;
        break;
    

    As you can see, it mimics the plugin activation senario, but it doesn’t actually activate the plugin. It includes the plugin file, calls the activate hook, then exits. It does all this without output buffering so you can see what’s happening.

    SO, if that’s already there, we just need to expose it. A bit of digging in wp-admin/plugins.php shows we need a nonce to verify. So we can copy that and study how the plugins list table builds its activation links. Then simply add an error scrape link on the inactive plugins. Click it, and see your errors.

    Just hook into plugin_action_links and add the link:

    <?php
    add_filter('plugin_action_links', 'wpse24278_add_scrape', 10, 2);
    /**
     * Add an "Error Scrape" action to inactive plugins.
     *
     * @uses    is_plugin_active
     * @return  array
     */
    function wpse24278_add_scrape($actions, $plugin)
    {
        global $status, $page, $s;
    
        // leave active plugins alone
        if (is_plugin_active($plugin)) {
            return $actions;
        }
    
        // build the url, identical to the activate URL, see the
        // plugings list table for more information.
        $url = add_query_arg(array(
            'action'            => 'error_scrape',
            'plugin'            => $plugin,
            'plugin_status'     => $status,
            'paged'             => $page,
            's'                 => $s,
        ), admin_url('plugins.php'));
    
        // add our action.
        $actions['error_scrape'] = sprintf(
            '<a href="%s" title="%s" class="edit">%s</a>',
            wp_nonce_url($url, 'plugin-activation-error_' . $plugin), // see `wp-admin/plugins.php` for the nonce name
            esc_attr__('Check for Errors', 'wpse'),
            esc_html__('Error Scrape', 'wpse')
        );
    
        return $actions;
    }
    

    Here is the above wrapped up in a plugin.

  2. Interesting question, so I had a look on Google and some guy named Jason had a solution:

    br_trigger_error('Some error message', E_USER_ERROR);
    
    function br_trigger_error($message, $errno) {
      if(isset($_GET['action'])
          &amp;&amp; $_GET['action'] == 'error_scrape') {
        echo '<strong>' . $message . '</strong>';
        exit;
    } else {
        trigger_error($message, $errno);
    }
    }
    

    From http://www.squarepenguin.com/wordpress/?p=6 that has more details as well.

  3. I just found a way, all props to itzco and hungrycoder. I’ve added the hook parameters.

    add_action( 'activated_plugin', 'save_error_wpse_24278', 10, 2 );
    
    function save_error_wpse_24278( $plugin, $network_wide )
    {
        file_put_contents( 
            WP_CONTENT_DIR. '/error_activation.html', 
            $plugin . ob_get_contents() 
        );
        //update_option( 'plugin_error',  ob_get_contents() );
    }