Skip to content

Commit

Permalink
[11.x] Introduces Exceptions facade (#50704)
Browse files Browse the repository at this point in the history
* Initial work on `Exceptions` facade

* Apply fixes from StyleCI

* Allows to fake expecific exceptions

* Adds `throwOnReport` and `throwReported`

* Apply fixes from StyleCI

* Fixes reporting of regular errors like 404 or 302

* More tests

* More tests

* Update src/Illuminate/Support/Testing/Fakes/ExceptionHandlerFake.php

Co-authored-by: Tim MacDonald <[email protected]>

* Update src/Illuminate/Support/Testing/Fakes/ExceptionHandlerFake.php

Co-authored-by: Tim MacDonald <[email protected]>

* Adjusts code

* formatting

* marker interface

* Apply fixes from StyleCI

---------

Co-authored-by: StyleCI Bot <[email protected]>
Co-authored-by: Dries Vints <[email protected]>
Co-authored-by: Tim MacDonald <[email protected]>
Co-authored-by: Taylor Otwell <[email protected]>
  • Loading branch information
5 people authored Apr 10, 2024
1 parent 7d40721 commit d3a051a
Show file tree
Hide file tree
Showing 5 changed files with 965 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

use Closure;
use Illuminate\Contracts\Debug\ExceptionHandler;
use Illuminate\Support\Facades\Exceptions;
use Illuminate\Support\Testing\Fakes\ExceptionHandlerFake;
use Illuminate\Testing\Assert;
use Illuminate\Validation\ValidationException;
use Symfony\Component\Console\Application as ConsoleApplication;
Expand All @@ -27,7 +29,11 @@ trait InteractsWithExceptionHandling
protected function withExceptionHandling()
{
if ($this->originalExceptionHandler) {
$this->app->instance(ExceptionHandler::class, $this->originalExceptionHandler);
$currentExceptionHandler = app(ExceptionHandler::class);

$currentExceptionHandler instanceof ExceptionHandlerFake
? $currentExceptionHandler->setHandler($this->originalExceptionHandler)
: $this->app->instance(ExceptionHandler::class, $this->originalExceptionHandler);
}

return $this;
Expand Down Expand Up @@ -63,10 +69,14 @@ protected function handleValidationExceptions()
protected function withoutExceptionHandling(array $except = [])
{
if ($this->originalExceptionHandler == null) {
$this->originalExceptionHandler = app(ExceptionHandler::class);
$currentExceptionHandler = app(ExceptionHandler::class);

$this->originalExceptionHandler = $currentExceptionHandler instanceof ExceptionHandlerFake
? $currentExceptionHandler->handler()
: $currentExceptionHandler;
}

$this->app->instance(ExceptionHandler::class, new class($this->originalExceptionHandler, $except) implements ExceptionHandler
$exceptionHandler = new class($this->originalExceptionHandler, $except) implements ExceptionHandler, WithoutExceptionHandlingHandler
{
protected $except;
protected $originalHandler;
Expand Down Expand Up @@ -145,7 +155,13 @@ public function renderForConsole($output, Throwable $e)
{
(new ConsoleApplication)->renderThrowable($e, $output);
}
});
};

$currentExceptionHandler = app(ExceptionHandler::class);

$currentExceptionHandler instanceof ExceptionHandlerFake
? $currentExceptionHandler->setHandler($exceptionHandler)
: $this->app->instance(ExceptionHandler::class, $exceptionHandler);

return $this;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace Illuminate\Foundation\Testing\Concerns;

interface WithoutExceptionHandlingHandler
{
//
}
68 changes: 68 additions & 0 deletions src/Illuminate/Support/Facades/Exceptions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

namespace Illuminate\Support\Facades;

use Illuminate\Contracts\Debug\ExceptionHandler;
use Illuminate\Support\Arr;
use Illuminate\Support\Testing\Fakes\ExceptionHandlerFake;

/**
* @method static void register()
* @method static \Illuminate\Foundation\Exceptions\ReportableHandler reportable(callable $reportUsing)
* @method static \Illuminate\Foundation\Exceptions\Handler renderable(callable $renderUsing)
* @method static \Illuminate\Foundation\Exceptions\Handler map(\Closure|string $from, \Closure|string|null $to = null)
* @method static \Illuminate\Foundation\Exceptions\Handler dontReport(array|string $exceptions)
* @method static \Illuminate\Foundation\Exceptions\Handler ignore(array|string $exceptions)
* @method static \Illuminate\Foundation\Exceptions\Handler dontFlash(array|string $attributes)
* @method static \Illuminate\Foundation\Exceptions\Handler level(string $type, void $level)
* @method static void report(\Throwable $e)
* @method static bool shouldReport(\Throwable $e)
* @method static \Illuminate\Foundation\Exceptions\Handler throttleUsing(callable $throttleUsing)
* @method static \Illuminate\Foundation\Exceptions\Handler stopIgnoring(array|string $exceptions)
* @method static \Illuminate\Foundation\Exceptions\Handler buildContextUsing(\Closure $contextCallback)
* @method static \Symfony\Component\HttpFoundation\Response render(\Illuminate\Http\Request $request, \Throwable $e)
* @method static \Illuminate\Foundation\Exceptions\Handler respondUsing(callable $callback)
* @method static \Illuminate\Foundation\Exceptions\Handler shouldRenderJsonWhen(callable $callback)
* @method static \Illuminate\Foundation\Exceptions\Handler dontReportDuplicates()
* @method static \Illuminate\Contracts\Debug\ExceptionHandler handler()
* @method static void assertNothingReported()
* @method static void assertReported(\Closure|string $exception)
* @method static void assertReportedCount(int $count)
* @method static void assertNotReported(\Closure|string $exception)
* @method static void renderForConsole(\Symfony\Component\Console\Output\OutputInterface $output, \Throwable $e)
* @method static \Illuminate\Support\Testing\Fakes\ExceptionHandlerFake throwFirstReported()
* @method static \Illuminate\Support\Testing\Fakes\ExceptionHandlerFake setHandler(\Illuminate\Contracts\Debug\ExceptionHandler $handler)
*
* @see \Illuminate\Foundation\Exceptions\Handler
* @see \Illuminate\Contracts\Debug\ExceptionHandler
* @see \Illuminate\Support\Testing\Fakes\ExceptionHandlerFake
*/
class Exceptions extends Facade
{
/**
* Replace the bound instance with a fake.
*
* @param array<int, class-string<\Throwable>>|class-string<\Throwable> $exceptions
* @return \Illuminate\Support\Testing\Fakes\ExceptionHandlerFake
*/
public static function fake(array|string $exceptions = [])
{
$exceptionHandler = static::isFake()
? static::getFacadeRoot()->handler()
: static::getFacadeRoot();

return tap(new ExceptionHandlerFake($exceptionHandler, Arr::wrap($exceptions)), function ($fake) {
static::swap($fake);
});
}

/**
* Get the registered name of the component.
*
* @return string
*/
protected static function getFacadeAccessor()
{
return ExceptionHandler::class;
}
}
Loading

0 comments on commit d3a051a

Please sign in to comment.