ldc-dam/app/Exceptions/Handler.php

185 lines
6.2 KiB
PHP
Raw Normal View History

2019-05-09 15:00:05 +02:00
<?php
namespace App\Exceptions;
2022-07-28 12:32:37 +02:00
use App\Enums\Legacy\ApiError;
use App\Enums\Legacy\ApiStatus;
use App\Exceptions\Api\ApiErrorException;
use App\Http\Resources\Api\ApiResponse as ApiResponseResource;
use App\Lib\Helper;
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 Kwaadpepper\ExceptionHandler\Exceptions\ExceptionHandler;
2022-07-28 12:32:37 +02:00
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
2022-04-19 11:52:41 +02:00
use Throwable;
2019-05-09 15:00:05 +02:00
class Handler extends ExceptionHandler
{
2022-04-20 15:23:31 +02:00
/**
* A list of exception types with their corresponding custom log levels.
*
* @var array<class-string<\Throwable>, \Psr\Log\LogLevel::*>
*/
2022-07-28 12:32:37 +02:00
protected $levels = [
ApiErrorException::class => \Psr\Log\LogLevel::WARNING
];
2022-04-20 15:23:31 +02:00
2019-05-09 15:00:05 +02:00
/**
* A list of the exception types that are not reported.
*
2022-04-20 15:23:31 +02:00
* @var array<int, class-string<\Throwable>>
2019-05-09 15:00:05 +02:00
*/
2022-07-28 12:32:37 +02:00
protected $dontReport = [
ApiErrorException::class,
];
2019-05-09 15:00:05 +02:00
/**
* A list of the inputs that are never flashed for validation exceptions.
*
2022-04-19 14:49:09 +02:00
* @var array<int, string>
2019-05-09 15:00:05 +02:00
*/
protected $dontFlash = [
2022-04-19 14:49:09 +02:00
'current_password',
2019-05-09 15:00:05 +02:00
'password',
'password_confirmation',
];
/**
2022-04-19 14:49:09 +02:00
* Register the exception handling callbacks for the application.
2019-05-09 15:00:05 +02:00
*
* @return void
*/
2022-04-19 14:49:09 +02:00
public function register()
2019-05-09 15:00:05 +02:00
{
2022-04-19 14:49:09 +02:00
$this->reportable(function (Throwable $e) {
});
2019-05-09 15:00:05 +02:00
}
2022-07-28 12:32:37 +02:00
/**
* Render an exception into an HTTP response.
*
* @param mixed $request
* @param \Throwable $e
* @return \Symfony\Component\HttpFoundation\Response
*
* @throws \Throwable If needed.
*/
public function render(mixed $request, Throwable $e)
{
if (Helper::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 api 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('\\', (string)$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 ApiResponseResource(
(object)array_merge($data, ['message' => $message, 'code' => $apiCode]),
ApiStatus::KO()
))->toResponse($request)->setStatusCode($httpCode);
}
2019-05-09 15:00:05 +02:00
}