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); } }