Skip to content

Commit

Permalink
Disable error page rendering
Browse files Browse the repository at this point in the history
  • Loading branch information
rubenvanassche committed Jun 6, 2024
1 parent e32750f commit 34db930
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 11 deletions.
121 changes: 113 additions & 8 deletions src/Commands/TestCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,21 @@

namespace Spatie\LaravelFlare\Commands;

use Closure;
use Composer\InstalledVersions;
use Exception;
use Illuminate\Config\Repository;
use Illuminate\Console\Command;
use Illuminate\Foundation\Exceptions\Handler;
use Illuminate\Foundation\Exceptions\ReportableHandler;
use Illuminate\Log\LogManager;
use Laravel\SerializableClosure\Support\ReflectionClosure;
use ReflectionException;
use ReflectionNamedType;
use ReflectionProperty;
use Spatie\FlareClient\Flare;
use Spatie\FlareClient\Http\Exceptions\BadResponseCode;
use Spatie\Ignition\Ignition;

class TestCommand extends Command
{
Expand Down Expand Up @@ -43,34 +51,131 @@ protected function checkFlareKey(): self
}

public function checkFlareLogger(): self
{
$configuredCorrectly = $this->shouldUseReportableCallbackLogger()
? $this->isValidReportableCallbackFlareLogger()
: $this->isValidConfigFlareLogger();

if($configuredCorrectly === false) {
die();
}

if ($this->config->get('flare.with_stack_frame_arguments') && ini_get('zend.exception_ignore_args')) {
$this->info('⚠️ The `zend.exception_ignore_args` php ini setting is enabled. This will prevent Flare from showing stack trace arguments.');
}

$this->info('✅ The Flare logging driver was configured correctly.');

return $this;
}

protected function shouldUseReportableCallbackLogger(): bool
{
return version_compare(app()->version(), '11.0.0', '>=');
}

protected function isValidConfigFlareLogger(): bool
{
$failures = $this->resolveConfigFlareLoggerFailures();

foreach ($failures as $failure) {
$this->info($failure);
}

return empty($failures);
}

/** @return string[] */
protected function resolveConfigFlareLoggerFailures(): array
{
$defaultLogChannel = $this->config->get('logging.default');

$activeStack = $this->config->get("logging.channels.{$defaultLogChannel}");

$failures = [];

if (is_null($activeStack)) {
$this->info("❌ The default logging channel `{$defaultLogChannel}` is not configured in the `logging` config file");
$failures[] = "❌ The default logging channel `{$defaultLogChannel}` is not configured in the `logging` config file";
}

if (! isset($activeStack['channels']) || ! in_array('flare', $activeStack['channels'])) {
$this->info("❌ The logging channel `{$defaultLogChannel}` does not contain the 'flare' channel");
$failures[] = "❌ The logging channel `{$defaultLogChannel}` does not contain the 'flare' channel";
}

if (is_null($this->config->get('logging.channels.flare'))) {
$this->info('❌ There is no logging channel named `flare` in the `logging` config file');
$failures[] = '❌ There is no logging channel named `flare` in the `logging` config file';
}

if ($this->config->get('logging.channels.flare.driver') !== 'flare') {
$this->info('❌ The `flare` logging channel defined in the `logging` config file is not set to `flare`.');
$failures[] = '❌ The `flare` logging channel defined in the `logging` config file is not set to `flare`.';
}

if ($this->config->get('flare.with_stack_frame_arguments') && ini_get('zend.exception_ignore_args')) {
$this->info('⚠️ The `zend.exception_ignore_args` php ini setting is enabled. This will prevent Flare from showing stack trace arguments.');
return $failures;
}

protected function isValidReportableCallbackFlareLogger(): bool
{
$configLoggerFailures = $this->resolveConfigFlareLoggerFailures();

$hasReportableCallbackFlareLogger = $this->hasReportableCallbackFlareLogger();

if(empty($configLoggerFailures) && $hasReportableCallbackFlareLogger) {
$this->info('❌ The Flare logger was defined in your Laravel `logging.php` config file and `bootstrap/app.php` file which can cause duplicate errors. Please remove the Flare logger from your `logging.php` config file.');
}

$this->info('✅ The Flare logging driver was configured correctly.');
if ($hasReportableCallbackFlareLogger) {
return true;
}

return $this;
if(empty($configLoggerFailures)) {
return true;
}

$this->info('❌ The Flare logging driver was not configured correctly.');
$this->newLine();
$this->info('<fg=default;bg=default>Please ensure the following code is present in your `<fg=green>bootstrap/app.php</>` file:</>');
$this->newLine();
$this->info('<fg=default;bg=default>-><fg=green>withExceptions</>(<fg=blue>function</> (<fg=red>Exceptions</> $exceptions) {</>');
$this->info('<fg=default;bg=default> <fg=red>Flare</>::<fg=green>handles</>($exceptions);</>');
$this->info('<fg=default;bg=default>})-><fg=green>create</>();</>');

return false;
}

protected function hasReportableCallbackFlareLogger(): bool
{
try {
$handler = app(Handler::class);

$reflection = new ReflectionProperty($handler, 'reportCallbacks');
$reportCallbacks = $reflection->getValue($handler);

foreach ($reportCallbacks as $reportCallback) {
if (! $reportCallback instanceof ReportableHandler) {
continue;
}

$reflection = new ReflectionProperty($reportCallback, 'callback');
$callback = $reflection->getValue($reportCallback);

if (! $callback instanceof Closure) {
return false;
}

$reflection = new ReflectionClosure($callback);
$closureReturnTypeReflection = $reflection->getReturnType();

if (! $closureReturnTypeReflection instanceof ReflectionNamedType) {
return false;
}

return $closureReturnTypeReflection->getName() === Ignition::class;
}
} catch (ReflectionException $exception) {
return false;
}

return false;
}

protected function sendTestException(): void
Expand Down
2 changes: 1 addition & 1 deletion src/Exceptions/InvalidConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ public function getSolution(): Solution

return BaseSolution::create()
->setSolutionTitle('You provided an invalid log level')
->setSolutionDescription("Please change the log level in your `config/logging.php` file. Valid log levels are {$validLogLevelsString}.");
->setSolutionDescription("Please change the log level in your `config/logging.php` file or in `bootstrap/app.php`. Valid log levels are {$validLogLevelsString}.");
}
}
17 changes: 16 additions & 1 deletion src/Facades/Flare.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@

namespace Spatie\LaravelFlare\Facades;

use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Support\Facades\Facade;
use Spatie\FlareClient\Flare as FlareClient;
use Spatie\Ignition\Ignition;
use Spatie\LaravelFlare\Support\SentReports;
use Throwable;

/**
* @method static void glow(string $name, string $messageLevel = \Spatie\FlareClient\Enums\MessageLevels::INFO, array $metaData = [])
Expand All @@ -16,7 +20,18 @@ class Flare extends Facade
{
protected static function getFacadeAccessor()
{
return \Spatie\FlareClient\Flare::class;
return FlareClient::class;
}

public static function handles(Exceptions $exceptions): void
{
$exceptions->reportable(static function (Throwable $exception): Ignition {
$flare = app(Ignition::class);

$flare->handleException($exception);

return $flare;
});
}

public static function sentReports(): SentReports
Expand Down
4 changes: 3 additions & 1 deletion src/FlareServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,9 @@ protected function registerIgnition(): void

$this->app->singleton(
Ignition::class,
fn () => (new Ignition($this->app->make(Flare::class)))->applicationPath(base_path())
fn () => (new Ignition($this->app->make(Flare::class)))
->shouldDisplayException(false)
->applicationPath(base_path())
);
}

Expand Down

0 comments on commit 34db930

Please sign in to comment.