4242use Symfony \Component \HttpKernel \Exception \HttpExceptionInterface ;
4343use Symfony \Component \HttpKernel \Exception \NotFoundHttpException ;
4444use Throwable ;
45+ use WeakMap ;
4546
4647class Handler implements ExceptionHandlerContract
4748{
@@ -119,6 +120,20 @@ class Handler implements ExceptionHandlerContract
119120 'password_confirmation ' ,
120121 ];
121122
123+ /**
124+ * Indicates that exception reporting should be deduplicated.
125+ *
126+ * @var bool
127+ */
128+ protected $ deduplicateReporting = false ;
129+
130+ /**
131+ * The already reported exception map.
132+ *
133+ * @var \WeakMap
134+ */
135+ protected $ reportedExceptionMap ;
136+
122137 /**
123138 * Create a new exception handler instance.
124139 *
@@ -129,6 +144,8 @@ public function __construct(Container $container)
129144 {
130145 $ this ->container = $ container ;
131146
147+ $ this ->reportedExceptionMap = new WeakMap ;
148+
132149 $ this ->register ();
133150 }
134151
@@ -260,6 +277,8 @@ public function report(Throwable $e)
260277 */
261278 protected function reportThrowable (Throwable $ e ): void
262279 {
280+ $ this ->reportedExceptionMap [$ e ] = true ;
281+
263282 if (Reflector::isCallable ($ reportCallable = [$ e , 'report ' ]) &&
264283 $ this ->container ->call ($ reportCallable ) !== false ) {
265284 return ;
@@ -307,6 +326,10 @@ public function shouldReport(Throwable $e)
307326 */
308327 protected function shouldntReport (Throwable $ e )
309328 {
329+ if ($ this ->deduplicateReporting && ($ this ->reportedExceptionMap [$ e ] ?? false )) {
330+ return true ;
331+ }
332+
310333 $ dontReport = array_merge ($ this ->dontReport , $ this ->internalDontReport );
311334
312335 return ! is_null (Arr::first ($ dontReport , fn ($ type ) => $ e instanceof $ type ));
@@ -786,6 +809,18 @@ public function renderForConsole($output, Throwable $e)
786809 (new ConsoleApplication )->renderThrowable ($ e , $ output );
787810 }
788811
812+ /**
813+ * Do not report duplicate exceptions.
814+ *
815+ * @return $this
816+ */
817+ public function dontReportDuplicates ()
818+ {
819+ $ this ->deduplicateReporting = true ;
820+
821+ return $ this ;
822+ }
823+
789824 /**
790825 * Determine if the given exception is an HTTP exception.
791826 *
0 commit comments