, \Psr\Log\LogLevel::*> */ protected $levels = [ ApiErrorException::class => \Psr\Log\LogLevel::WARNING ]; /** * A list of the exception types that are not reported. * * @var array> */ protected $dontReport = [ ApiErrorException::class, ]; /** * A list of the inputs that are never flashed for validation exceptions. * * @var array */ protected $dontFlash = [ 'current_password', 'password', 'password_confirmation', ]; /** * Register the exception handling callbacks for the application. * * @return void */ public function register() { $this->reportable(function (Throwable $e) { }); } /** * 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); } }