Skip to content

Commit b6ecc7d

Browse files
Prevent unnecessary query logging on exceptions with a custom renderer (#56874)
1 parent 73713d5 commit b6ecc7d

File tree

2 files changed

+104
-1
lines changed

2 files changed

+104
-1
lines changed

src/Illuminate/Foundation/Providers/FoundationServiceProvider.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Illuminate\Contracts\Container\Container;
99
use Illuminate\Contracts\Events\Dispatcher;
1010
use Illuminate\Contracts\Foundation\Application;
11+
use Illuminate\Contracts\Foundation\ExceptionRenderer;
1112
use Illuminate\Contracts\Foundation\MaintenanceMode as MaintenanceModeContract;
1213
use Illuminate\Contracts\View\Factory;
1314
use Illuminate\Database\ConnectionInterface;
@@ -70,7 +71,7 @@ public function boot()
7071
], 'laravel-errors');
7172
}
7273

73-
if ($this->app->hasDebugModeEnabled()) {
74+
if ($this->app->hasDebugModeEnabled() && ! $this->app->has(ExceptionRenderer::class)) {
7475
$this->app->make(Listener::class)->registerListeners(
7576
$this->app->make(Dispatcher::class)
7677
);

tests/Integration/Foundation/Exceptions/RendererTest.php

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@
22

33
namespace Illuminate\Tests\Integration\Foundation\Exceptions;
44

5+
use Illuminate\Contracts\Events\Dispatcher;
6+
use Illuminate\Contracts\Foundation\ExceptionRenderer;
7+
use Illuminate\Foundation\Exceptions\Renderer\Listener;
58
use Illuminate\Foundation\Exceptions\Renderer\Renderer;
9+
use Illuminate\Foundation\Providers\FoundationServiceProvider;
10+
use Mockery;
611
use Orchestra\Testbench\Attributes\WithConfig;
712
use Orchestra\Testbench\TestCase;
813
use RuntimeException;
@@ -37,4 +42,101 @@ public function testItCanRenderExceptionPageUsingSymfonyIfRendererIsNotDefined()
3742
->assertSee('RuntimeException')
3843
->assertSee('Bad route!');
3944
}
45+
46+
#[WithConfig('app.debug', true)]
47+
public function testItCanRenderExceptionPageWithRendererWhenDebugEnabled()
48+
{
49+
$this->app->singleton(ExceptionRenderer::class, function () {
50+
return new class() implements ExceptionRenderer
51+
{
52+
public function render($throwable)
53+
{
54+
return response('Custom Exception Renderer: '.$throwable->getMessage(), 500);
55+
}
56+
};
57+
});
58+
59+
$this->assertTrue($this->app->bound(ExceptionRenderer::class));
60+
61+
$this->get('/failed')
62+
->assertInternalServerError()
63+
->assertSee('Custom Exception Renderer: Bad route!');
64+
}
65+
66+
#[WithConfig('app.debug', false)]
67+
public function testItDoesNotRenderExceptionPageWithRendererWhenDebugDisabled()
68+
{
69+
$this->app->singleton(ExceptionRenderer::class, function () {
70+
return new class() implements ExceptionRenderer
71+
{
72+
public function render($throwable)
73+
{
74+
return response('Custom Exception Renderer: '.$throwable->getMessage(), 500);
75+
}
76+
};
77+
});
78+
79+
$this->assertTrue($this->app->bound(ExceptionRenderer::class));
80+
81+
$this->get('/failed')
82+
->assertInternalServerError()
83+
->assertDontSee('Custom Exception Renderer: Bad route!');
84+
}
85+
86+
#[WithConfig('app.debug', false)]
87+
public function testItDoesNotRegisterListenersWhenDebugDisabled()
88+
{
89+
$this->app->forgetInstance(ExceptionRenderer::class);
90+
$this->assertFalse($this->app->bound(ExceptionRenderer::class));
91+
92+
$listener = Mockery::mock(Listener::class);
93+
$listener->shouldReceive('registerListeners')->never();
94+
95+
$this->app->instance(Listener::class, $listener);
96+
$this->app->instance(Dispatcher::class, Mockery::mock(Dispatcher::class));
97+
98+
$provider = $this->app->getProvider(FoundationServiceProvider::class);
99+
$provider->boot();
100+
}
101+
102+
#[WithConfig('app.debug', true)]
103+
public function testItDoesNotRegisterListenersWhenRendererBound()
104+
{
105+
$this->app->singleton(ExceptionRenderer::class, function () {
106+
return new class() implements ExceptionRenderer
107+
{
108+
public function render($throwable)
109+
{
110+
return response('Custom Exception Renderer: '.$throwable->getMessage(), 500);
111+
}
112+
};
113+
});
114+
115+
$this->assertTrue($this->app->bound(ExceptionRenderer::class));
116+
117+
$listener = Mockery::mock(Listener::class);
118+
$listener->shouldReceive('registerListeners')->never();
119+
120+
$this->app->instance(Listener::class, $listener);
121+
$this->app->instance(Dispatcher::class, Mockery::mock(Dispatcher::class));
122+
123+
$provider = $this->app->getProvider(FoundationServiceProvider::class);
124+
$provider->boot();
125+
}
126+
127+
#[WithConfig('app.debug', true)]
128+
public function testItRegistersListenersWhenRendererNotBound()
129+
{
130+
$this->app->forgetInstance(ExceptionRenderer::class);
131+
$this->assertFalse($this->app->bound(ExceptionRenderer::class));
132+
133+
$listener = Mockery::mock(Listener::class);
134+
$listener->shouldReceive('registerListeners')->once();
135+
136+
$this->app->instance(Listener::class, $listener);
137+
$this->app->instance(Dispatcher::class, Mockery::mock(Dispatcher::class));
138+
139+
$provider = $this->app->getProvider(FoundationServiceProvider::class);
140+
$provider->boot();
141+
}
40142
}

0 commit comments

Comments
 (0)