33namespace Pterodactyl \Exceptions ;
44
55use Exception ;
6- use Prologue \Alerts \Facades \Alert ;
76use Illuminate \Auth \AuthenticationException ;
87use Illuminate \Session \TokenMismatchException ;
98use Illuminate \Validation \ValidationException ;
109use Illuminate \Auth \Access \AuthorizationException ;
1110use Illuminate \Database \Eloquent \ModelNotFoundException ;
12- use Pterodactyl \Exceptions \Model \DataValidationException ;
1311use Symfony \Component \HttpKernel \Exception \HttpException ;
1412use Pterodactyl \Exceptions \Repository \RecordNotFoundException ;
1513use Illuminate \Foundation \Exceptions \Handler as ExceptionHandler ;
@@ -25,15 +23,23 @@ class Handler extends ExceptionHandler
2523 AuthenticationException::class,
2624 AuthorizationException::class,
2725 DisplayException::class,
28- DataValidationException::class,
29- DisplayValidationException::class,
3026 HttpException::class,
3127 ModelNotFoundException::class,
3228 RecordNotFoundException::class,
3329 TokenMismatchException::class,
3430 ValidationException::class,
3531 ];
3632
33+ /**
34+ * A list of the inputs that are never flashed for validation exceptions.
35+ *
36+ * @var array
37+ */
38+ protected $ dontFlash = [
39+ 'password ' ,
40+ 'password_confirmation ' ,
41+ ];
42+
3743 /**
3844 * Report or log an exception.
3945 *
@@ -53,41 +59,78 @@ public function report(Exception $exception)
5359 *
5460 * @param \Illuminate\Http\Request $request
5561 * @param \Exception $exception
56- * @return \Illuminate\Http\JsonResponse|\ Symfony\Component\HttpFoundation\Response
62+ * @return \Symfony\Component\HttpFoundation\Response
5763 *
5864 * @throws \Exception
5965 */
6066 public function render ($ request , Exception $ exception )
6167 {
62- if ($ request-> expectsJson () || $ request -> isJson () || $ request -> is (... config ( ' pterodactyl.json_routes ' ))) {
63- $ exception = $ this -> prepareException ( $ exception );
68+ return parent :: render ($ request, $ exception );
69+ }
6470
65- if (config ('app.debug ' ) || $ this ->isHttpException ($ exception ) || $ exception instanceof DisplayException) {
66- $ displayError = $ exception ->getMessage ();
67- } else {
68- $ displayError = 'An unhandled exception was encountered with this request. ' ;
71+ /**
72+ * @param \Illuminate\Http\Request $request
73+ * @param \Illuminate\Validation\ValidationException $exception
74+ * @return \Illuminate\Http\JsonResponse
75+ */
76+ public function invalidJson ($ request , ValidationException $ exception )
77+ {
78+ $ codes = collect ($ exception ->validator ->failed ())->mapWithKeys (function ($ reasons , $ field ) {
79+ $ cleaned = [];
80+ foreach ($ reasons as $ reason => $ attrs ) {
81+ $ cleaned [] = snake_case ($ reason );
6982 }
7083
71- $ response = response ()->json (
72- [
73- 'error ' => $ displayError ,
74- 'type ' => (! config ('app.debug ' )) ? null : class_basename ($ exception ),
75- 'http_code ' => (method_exists ($ exception , 'getStatusCode ' )) ? $ exception ->getStatusCode () : 500 ,
76- 'trace ' => (! config ('app.debug ' )) ? null : $ exception ->getTrace (),
77- ],
78- $ this ->isHttpException ($ exception ) ? $ exception ->getStatusCode () : 500 ,
79- $ this ->isHttpException ($ exception ) ? $ exception ->getHeaders () : [],
80- JSON_UNESCAPED_SLASHES
81- );
84+ return [$ field => $ cleaned ];
85+ })->toArray ();
86+
87+ $ errors = collect ($ exception ->errors ())->map (function ($ errors , $ field ) use ($ codes ) {
88+ $ response = [];
89+ foreach ($ errors as $ key => $ error ) {
90+ $ response [] = [
91+ 'code ' => array_get ($ codes , $ field . '. ' . $ key ),
92+ 'detail ' => $ error ,
93+ 'source ' => ['field ' => $ field ],
94+ ];
95+ }
96+
97+ return $ response ;
98+ })->flatMap (function ($ errors ) {
99+ return $ errors ;
100+ })->toArray ();
101+
102+ return response ()->json (['errors ' => $ errors ], $ exception ->status );
103+ }
82104
83- parent ::report ($ exception );
84- } elseif ($ exception instanceof DisplayException) {
85- Alert::danger ($ exception ->getMessage ())->flash ();
105+ /**
106+ * Return the exception as a JSONAPI representation for use on API requests.
107+ *
108+ * @param \Exception $exception
109+ * @param array $override
110+ * @return array
111+ */
112+ public static function convertToArray (Exception $ exception , array $ override = []): array
113+ {
114+ $ error = [
115+ 'code ' => class_basename ($ exception ),
116+ 'status ' => method_exists ($ exception , 'getStatusCode ' ) ? strval ($ exception ->getStatusCode ()) : '500 ' ,
117+ 'detail ' => 'An error was encountered while processing this request. ' ,
118+ ];
86119
87- return redirect ()->back ()->withInput ();
120+ if (config ('app.debug ' )) {
121+ $ error = array_merge ($ error , [
122+ 'detail ' => $ exception ->getMessage (),
123+ 'source ' => [
124+ 'line ' => $ exception ->getLine (),
125+ 'file ' => str_replace (base_path (), '' , $ exception ->getFile ()),
126+ ],
127+ 'meta ' => [
128+ 'trace ' => explode ("\n" , $ exception ->getTraceAsString ()),
129+ ],
130+ ]);
88131 }
89132
90- return ( isset ( $ response )) ? $ response : parent :: render ( $ request , $ exception ) ;
133+ return [ ' errors ' => [ array_merge ( $ error , $ override )]] ;
91134 }
92135
93136 /**
@@ -105,4 +148,16 @@ protected function unauthenticated($request, AuthenticationException $exception)
105148
106149 return redirect ()->guest (route ('auth.login ' ));
107150 }
151+
152+ /**
153+ * Converts an exception into an array to render in the response. Overrides
154+ * Laravel's built-in converter to output as a JSONAPI spec compliant object.
155+ *
156+ * @param \Exception $exception
157+ * @return array
158+ */
159+ protected function convertExceptionToArray (Exception $ exception )
160+ {
161+ return self ::convertToArray ($ exception );
162+ }
108163}
0 commit comments