ldc-flucollector/app/Exceptions/Handler.php
Jérémy Munsch c0c1608ad5
Api calls ok
2023-10-02 12:26:41 +02:00

175 lines
5.9 KiB
PHP

<?php
namespace App\Exceptions;
use App\Enums\Api\ApiError;
use App\Enums\Api\ApiStatus;
use App\Http\Resources\Api\ApiResponse;
use App\Lib\ApiHelper;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Http\Exceptions\ThrottleRequestsException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
class Handler extends ExceptionHandler
{
/**
* A list of the exception types that are not reported.
*
* @var array
*/
protected $dontReport = [
ApiErrorException::class,
RedirectTo::class
];
/**
* A list of the inputs that are never flashed for validation exceptions.
*
* @var array
*/
protected $dontFlash = [
'password',
'password_confirmation',
];
/**
* Register the exception handling callbacks for the application.
*
* @return void
*/
public function register(): void
{
$this->reportable(function (\Throwable $e) {
if (app()->bound('sentry')) {
app('sentry')->captureException($e);
}
});
}
/**
* Render an exception into an HTTP response.
*
* @param mixed $request
* @param \Throwable $e
* @return \Symfony\Component\HttpFoundation\Response
*/
public function render(mixed $request, \Throwable $e): Response
{
if (ApiHelper::isRequestForApi($request) and $request->isJson()) {
return $this->handleApiException($request, $e);
} //end if
// @codeCoverageIgnoreStart
return parent::render($request, $e);
// @codeCoverageIgnoreEnd
}
/**
* Generate a json response for any apiV4 error case.
*
* @param \Illuminate\Http\Request $request
* @param \Throwable $e
* @return \Illuminate\Http\JsonResponse
*/
private function handleApiException(Request $request, \Throwable $e): JsonResponse
{
switch (get_class($e)) {
case AuthenticationException::class:
/** @var AuthenticationException $e */
return $this->getReponse(
$request,
401,
ApiError::apiAuthFailed->value(),
sprintf('%s, %s', ApiError::apiAuthFailed->label(), $e->getMessage())
);
case MethodNotAllowedHttpException::class:
/** @var MethodNotAllowedHttpException $e */
return $this->getReponse(
$request,
$e->getStatusCode(),
ApiError::methodNotAllowed->value(),
sprintf('%s, %s', ApiError::methodNotAllowed->label(), $e->getMessage())
);
case ValidationException::class:
/** @var ValidationException $e */
return $this->getReponse(
$request,
$e->status,
ApiError::validationFailed->value(),
sprintf(ApiError::validationFailed->label(), $e->getMessage()),
['errors' => $e->errors()]
);
case ModelNotFoundException::class:
/** @var ModelNotFoundException $e */
return $this->getReponse(
$request,
404,
ApiError::modelNotFound->value(),
sprintf(
ApiError::modelNotFound->label(),
\array_slice(explode('\\', $e->getModel()), -1)[0]
)
);
case ApiErrorException::class:
/** @var ApiErrorException $e */
return $this->getReponse(
$request,
$e->getStatusCode(),
$e->getCode(),
$e->getMessage()
);
case ThrottleRequestsException::class:
/** @var ThrottleRequestsException $e */
return $this->getReponse(
$request,
429,
ApiError::throttleRequestsException->value(),
ApiError::throttleRequestsException->label()
);
case AuthorizationException::class:
/** @var AuthorizationException $e */
return $this->getReponse(
$request,
403,
ApiError::authorizationException->value(),
ApiError::authorizationException->label()
);
} //end switch
// @codeCoverageIgnoreStart
if (config('app.env') === 'testing') {
// phpcs:ignore Squiz.PHP.DiscouragedFunctions.Found
print_r((string)$e);
}
return $this->getReponse($request, 500, \intval($e->getCode()), $e->getMessage());
// @codeCoverageIgnoreEnd
}
/**
* Generate an Api json response.
*
* @param \Illuminate\Http\Request $request
* @param integer $httpCode
* @param integer $apiCode
* @param string $message
* @param array $data
* @return \Illuminate\Http\JsonResponse
*/
private static function getReponse(
Request $request,
int $httpCode,
int $apiCode,
string $message,
array $data = []
): JsonResponse {
return (new ApiResponse(
(object)array_merge($data, ['message' => $message, 'code' => $apiCode]),
ApiStatus::KO
))->toResponse($request)->setStatusCode($httpCode);
}
}