Skip to content

Instantly share code, notes, and snippets.

@Zeitwaechter
Last active September 16, 2023 16:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Zeitwaechter/b45842df7ffe9c7cf720c84dc7e3624b to your computer and use it in GitHub Desktop.
Save Zeitwaechter/b45842df7ffe9c7cf720c84dc7e3624b to your computer and use it in GitHub Desktop.
laravel api generalized http exception responses
<?php
namespace App\Exceptions;
use App\Http\Controllers\Traits\HasHttpResponses;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Session\TokenMismatchException;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Throwable;
/**
* Class Handler
*/
class Handler extends ExceptionHandler
{
use HasHttpResponses;
/**
* The list of the inputs that are never flashed to the session on validation exceptions.
*
* @var array<int, string>
*/
protected $dontFlash
= [
'current_password',
'password',
'password_confirmation',
];
/**
* Register the exception handling callbacks for the application.
*/
public function register(): void
{
$this->reportable(function (Throwable $exception) {
//
});
}
/**
* Render an exception into an HTTP response.
*
* @param $request
* @param Throwable $e
*
* @return JsonResponse|RedirectResponse|Response
*
* @throws Throwable
*/
public function render($request, Throwable $e): Response|JsonResponse|RedirectResponse
{
if ($e instanceof AuthenticationException) {
return $this->customExceptionReturnHandling(
request: $request,
message: 'You are not authorized to use this route. ' .
'Are you logged in?',
code: 401,
);
}
if ($e instanceof AccessDeniedHttpException) {
return $this->customExceptionReturnHandling(
request: $request,
message: 'You are not authorized or already logged in.',
code: 403,
);
}
if ($e instanceof TokenMismatchException) {
return $this->customExceptionReturnHandling(
request: $request,
message: 'You are already logged in or your CSRF-Token is mismatching. ' .
'Is your CSRF Token attached as X-XSRF-TOKEN header param?',
code: 403,
);
}
if ($e instanceof ModelNotFoundException) {
return $this->customExceptionReturnHandling(
request: $request,
message: 'Requested data or Resource not found.',
code: 404,
);
}
if ($e instanceof NotFoundHttpException) {
return $this->customExceptionReturnHandling(
request: $request,
message: 'Requested route [' . $request->getPathInfo() . '] does not exist.',
code: 404,
);
}
if ($e instanceof \Error) {
return $this->customExceptionReturnHandling(
request: $request,
message: 'Screw up from our side. Server will be right back...',
code: 500,
);
}
return parent::render($request, $e);
}
/**
* @param Request $request
* @param string $message
* @param int $code
*
* @return Response|JsonResponse
*/
private function customExceptionReturnHandling(Request $request, string $message, int $code): Response|JsonResponse
{
if ($request->wantsJson()) {
return $this->error(
message: $message,
code: $code,
);
}
abort($code);
}
}
<?php
namespace App\Helpers\Traits;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Resources\Json\ResourceCollection;
/**
* Trait HttpResponses
*/
trait HasHttpResponses
{
/**
* @param array|ResourceCollection $payload
* @param string $message
* @param int $code
*
* @return JsonResponse
*/
protected function success(array|ResourceCollection $payload, string $message = 'OK', int $code = 200): JsonResponse
{
return new JsonResponse(
[
'message' => $message,
'data' => $payload,
],
$code,
);
}
/**
* @param array $payload
* @param string $message
* @param int $code
*
* @return JsonResponse
*/
protected function error(array $payload = [], string $message = 'Error', int $code = 500): JsonResponse
{
return new JsonResponse(
[
'message' => $message,
'data' => $payload,
],
$code,
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment