From 487b7480af2bfea14b738cd4f9489bf440f3c6af Mon Sep 17 00:00:00 2001 From: Nabeel Shahzad Date: Thu, 22 Feb 2018 10:14:12 -0600 Subject: [PATCH] Refactor how errors are handled --- app/Exceptions/Handler.php | 80 +++++++++++++++++++----------- app/Exceptions/SettingNotFound.php | 4 +- 2 files changed, 53 insertions(+), 31 deletions(-) diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index 070f153f..219ba4d6 100755 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -8,6 +8,8 @@ use Illuminate\Database\Eloquent\ModelNotFoundException; use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; use Illuminate\Validation\ValidationException; use Log; +use Symfony\Component\HttpKernel\Exception\HttpException; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; class Handler extends ExceptionHandler { @@ -37,66 +39,84 @@ class Handler extends ExceptionHandler parent::report($exception); } + /** + * Create an error message + * @param $status_code + * @param $message + * @return array + */ + protected function createError($status_code, $message) + { + return [ + 'error' => [ + 'status' => $status_code, + 'message' => $message, + ] + ]; + } + /** * Render an exception into an HTTP response. * * @param \Illuminate\Http\Request $request * @param \Exception $exception - * @return \Illuminate\Http\Response + * @return mixed */ public function render($request, Exception $exception) { - if ($exception instanceof \Symfony\Component\HttpKernel\Exception\HttpException - && $exception->getStatusCode() == 403) { - return redirect()->guest('login'); - } - if($request->is('api/*')) { - $error = [ - 'error' => [ - 'code' => $exception->getCode(), - 'message' => $exception->getMessage(), - ] - ]; + $headers = []; - $status = 400; - $http_code = $exception->getCode(); + Log::error('API Error', $exception->getTrace()); - Log::error($exception->getMessage()); - - if ($this->isHttpException($exception)) { - $status = $exception->getStatusCode(); - $http_code = $exception->getStatusCode(); + if($exception instanceof ModelNotFoundException || + $exception instanceof NotFoundHttpException) { + $error = $this->createError(404, $exception->getMessage()); } - if($exception instanceof ModelNotFoundException) { - $status = 404; - $http_code = 404; + # These are application errors. Custom exceptions should + # be extending HttpException + elseif ($exception instanceof HttpException) { + + $error = $this->createError( + $exception->getStatusCode(), + $exception->getMessage() + ); + + $headers = $exception->getHeaders(); } - if($exception instanceof ValidationException) { - $status = 400; - $http_code = 400; - - $errors = $exception->errors(); + # Create the detailed errors from the validation errors + elseif($exception instanceof ValidationException) { $error_messages = []; + $errors = $exception->errors(); foreach($errors as $field => $error) { $error_messages[] = implode(', ', $error); } - $error['error']['message'] = implode(', ', $error_messages); + $message = implode(', ', $error_messages); + $error = $this->createError(400, $message); $error['error']['errors'] = $errors; + Log::error('Validation errors', $errors); } + else { + $error = $this->createError(400, $exception->getMessage()); + } + # Only add trace if in dev if(config('app.env') === 'dev') { $error['error']['trace'] = $exception->getTrace()[0]; } - $error['error']['http_code'] = $http_code; - return response()->json($error, $status); + return response()->json($error, $error['error']['status'], $headers); + } + + if ($exception instanceof HttpException + && $exception->getStatusCode() === 403) { + return redirect()->guest('login'); } return parent::render($request, $exception); diff --git a/app/Exceptions/SettingNotFound.php b/app/Exceptions/SettingNotFound.php index 666102a8..9d3d1c22 100644 --- a/app/Exceptions/SettingNotFound.php +++ b/app/Exceptions/SettingNotFound.php @@ -5,7 +5,9 @@ namespace App\Exceptions; -class SettingNotFound extends \Exception +use Symfony\Component\HttpKernel\Exception\HttpException; + +class SettingNotFound extends HttpException { }