Skip to content

Instantly share code, notes, and snippets.

@cfaria
Last active February 2, 2024 20:44
Show Gist options
  • Save cfaria/7eb83ca2853cb062fd7f6365c9bd6de2 to your computer and use it in GitHub Desktop.
Save cfaria/7eb83ca2853cb062fd7f6365c9bd6de2 to your computer and use it in GitHub Desktop.
Prevent E_NOTICE, E_WARNING, E_DEPRECATED errors WSOD in Sage 10
<?php
namespace App\Providers;
use Roots\Acorn\ServiceProvider;
class ThemeServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
$this->app->booted(
function($app) {
set_error_handler(function ($level, $message, $file = '', $line = 0, $context = []) {
// Check if this error level is handled by error reporting
if (error_reporting() & $level) {
// Return false for any error levels that should
// be handled by the built in PHP error handler.
if ($level & (E_WARNING | E_NOTICE | E_DEPRECATED)) {
echo "<br />\n";
echo "<b>ERROR</b> [$level] $message<br />\n";
echo " Fatal error on line $line in file $file";
echo ", PHP " . PHP_VERSION . " (" . PHP_OS . ")<br />\n";
echo "Aborting...<br />\n";
return false;
}
// Throw an exception to be handled by Laravel for all other errors.
throw new \ErrorException($message, 0, $level, $file, $line);
}
});
}
);
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
}
}
@mike-sheppard
Copy link

mike-sheppard commented May 7, 2021

aha yeah I see, how about only outputting to admin_footer/footer and prevent display in ajax, ie. just log to the logfile?

Something like this..

// app/Providers/ThemeServiceProvider.php
<?php

namespace App\Providers;

use ErrorHelper;
use function Roots\view;
use Illuminate\Support\Facades\Log;
use Roots\Acorn\ServiceProvider;

class ThemeServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        $this->app->booted(
            function ($app) {
                set_error_handler(function ($level, $message, $file = '', $line = 0, $context = []) {
                    // Check if this error level is handled by error reporting
                    if (error_reporting() & $level) {
                        // Return false for any error levels that should be handled by the built in PHP error handler.
                        if ($level & (E_WARNING | E_NOTICE | E_DEPRECATED)) {
                            $error_label = ErrorHelper::getErrorTypeByValue($level) ?? '';
                            $error_output = view('admin.error', [
                                'error_label' => $error_label,
                                'message'     => $message,
                                'file'        => $file,
                                'line'        => $line,
                            ]);

                            if (is_admin() && !wp_doing_ajax()) {
                                add_action('admin_footer', function () use ($error_output) {
                                    echo $error_output;
                                });
                            } elseif (!wp_doing_ajax()) {
                                add_action('footer', function () use ($error_output) {
                                    echo $error_output;
                                });
                            }

                            // Also add to logfile / slack
                            $logfile_message = "Error displayed: {$error_label} - {$message}\n File: {$file}\n Line: {$line}";
                            (WP_ENV === 'development') ? Log::info($logfile_message) : Log::channel('slack')->warning($logfile_message);

                            return false;
                        }

                        // Throw an exception to be handled by Laravel for all other errors.
                        throw new \ErrorException($message, 0, $level, $file, $line);
                    }
                });
            }
        );

    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }
}
// ErrorHelper.php
<?php
class ErrorHelper
{
    public static function getErrorTypeByValue($type)
    {
        $constants = get_defined_constants(true);

        foreach ($constants['Core'] as $key => $value) { // Each Core constant
            if (preg_match('/^E_/', $key)) { // Check error constants
                if ($type == $value) {
                    return $key;
                }

            }
        }
    }

}

views/admin/error.blade.php

<pre style='position: fixed; z-index: 9999999; bottom: 1rem; right: 1rem; background: #eee; padding: 1rem; border-radius: 5px; box-shadow: 0 0 5px rgb(0 0 0 / 10%); border-left: 5px solid #ff5722; line-height: 1.8; max-width: 80%; overflow: scroll;'>
  <div style="position: absolute; top: 0; right: 0; font-size: 2rem; cursor: pointer; padding: 5px; line-height: 1;" onclick="return this.parentNode.remove();">&times;</div>
  <strong>{{ $error_label }}</strong> {{ $message }}
  File: {{ $file }}
  Line: {{ $line }}
</pre>

@mike-sheppard
Copy link

mike-sheppard commented May 7, 2021

In your ajax scenario, maybe return with one of these?

if (wp_doing_ajax()) {
    ...
    wp_send_json( $response:mixed, $status_code:integer|null, $options:integer )
    wp_send_json_error( $data:mixed|null, $status_code:integer|null, $options:integer )
    ...
}

Docs: wp_send_json
Docs: wp_send_json_error

@cfaria
Copy link
Author

cfaria commented May 7, 2021

Works like a charm Mike... even with Ajax requests without using wp_send_json or wp_send_json_error.

Thank you again ;D

@hadronix
Copy link

🙏 🙌

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