1616use Symfony \Component \HttpKernel \Exception \AccessDeniedHttpException ;
1717use Symfony \Component \HttpKernel \Exception \HttpExceptionInterface ;
1818use Symfony \Component \Security \Core \Exception \AccessDeniedException ;
19+ use Symfony \Component \Validator \ConstraintViolationInterface ;
20+ use Symfony \Component \Validator \Exception \ValidationFailedException ;
1921use Symfony \Component \Validator \Exception \ValidatorException ;
2022
2123class ExceptionListener
@@ -36,33 +38,82 @@ public function onKernelException(ExceptionEvent $event): void
3638 {
3739 $ exception = $ event ->getThrowable ();
3840
41+ if ($ exception instanceof ValidationFailedException) {
42+ $ event ->setResponse (
43+ new JsonResponse ([
44+ 'message ' => 'Validation failed ' ,
45+ 'errors ' => $ this ->parseFlatValidationMessage ($ exception ->getMessage ()),
46+ ], 422 )
47+ );
48+
49+ return ;
50+ }
51+
3952 foreach (self ::EXCEPTION_STATUS_MAP as $ class => $ statusCode ) {
4053 if ($ exception instanceof $ class ) {
41- $ status = $ statusCode ?? $ exception ->getStatusCode ();
54+ $ status = $ statusCode ?? (
55+ method_exists ($ exception , 'getStatusCode ' )
56+ ? $ exception ->getStatusCode ()
57+ : 400
58+ );
59+
4260 $ event ->setResponse (
4361 new JsonResponse ([
44- 'message ' => $ exception ->getMessage ()
62+ 'message ' => $ exception ->getMessage (),
4563 ], $ status )
4664 );
65+
4766 return ;
4867 }
4968 }
5069
5170 if ($ exception instanceof HttpExceptionInterface) {
5271 $ event ->setResponse (
5372 new JsonResponse ([
54- 'message ' => $ exception ->getMessage ()
73+ 'message ' => $ exception ->getMessage (),
5574 ], $ exception ->getStatusCode ())
5675 );
76+
5777 return ;
5878 }
5979
6080 if ($ exception instanceof Exception) {
6181 $ event ->setResponse (
6282 new JsonResponse ([
63- 'message ' => $ exception ->getMessage ()
83+ 'message ' => $ exception ->getMessage (),
6484 ], 500 )
6585 );
6686 }
6787 }
88+
89+ /**
90+ * @return array<string, array<int, string>>
91+ */
92+ private function parseFlatValidationMessage (string $ message ): array
93+ {
94+ $ errors = [];
95+ $ lines = preg_split ('/\r\n|\r|\n/ ' , $ message ) ?: [];
96+
97+ foreach ($ lines as $ line ) {
98+ $ line = trim ($ line );
99+
100+ if ($ line === '' ) {
101+ continue ;
102+ }
103+
104+ $ parts = explode (': ' , $ line , 2 );
105+
106+ if (count ($ parts ) !== 2 ) {
107+ $ errors ['_global ' ][] = $ line ;
108+ continue ;
109+ }
110+
111+ $ field = trim ($ parts [0 ]);
112+ $ errorMessage = trim ($ parts [1 ]);
113+
114+ $ errors [$ field ][] = $ errorMessage ;
115+ }
116+
117+ return $ errors ;
118+ }
68119}
0 commit comments