Factory method to create a new exception with a normalized error message

@param RequestInterface  $request  Request
@param ResponseInterface $response Response received
@param \Exception        $previous Previous exception

@return self
486849
public static function create(
        RequestInterface $request,
        ResponseInterface $response = null,
        \Exception $previous = null
    ) {
        if (!$response) {
            return new self('Error completing request', $request, null, $previous);
        }

        $level = $response->getStatusCode()[0];
        if ($level == '4') {
            $label = 'Client error response';
            $className = __NAMESPACE__ . '\\ClientException';
        } elseif ($level == '5') {
            $label = 'Server error response';
            $className = __NAMESPACE__ . '\\ServerException';
        } else {
            $label = 'Unsuccessful response';
            $className = __CLASS__;
        }

        $message = $label . ' [url] ' . $request->getUrl()
            . ' [status code] ' . $response->getStatusCode()
            . ' [reason phrase] ' . $response->getReasonPhrase();

        return new $className($message, $request, $response, $previous);
    }
353346
protected function createApiException(Request $request, Response $response)
    {
        //$errors = json_decode((string) $response->getBody());

        return new HttpRequestException(
            $response->getCode(),
            $response->getBody(),
            $request,
            $response
        );
    }
235917
public function addFailedRequestWithException(RequestInterface $request, \Exception $exception)
    {
        $this->add($exception)
             ->addFailedRequest($request)
             ->exceptionForRequest[spl_object_hash($request)] = $exception;

        return $this;
    }
844875
public static function createOnException(ChannelInterface $channel, Delivery $delivery, Exception $previous)
    {
        return new self(
            sprintf(
                'An error has occurred during the notification process of message "%s" for channel "%s".'
                .' Exception : %s - %s',
                $delivery->getMessage(),
                get_class($channel),
                get_class($previous),
                $previous->getMessage()
            ),
            0,
            $previous
        );
    }
917617
public function addFailure(RequestInterface $request, Exception $exception): void
    {
        $this->lastRequest = $request;
        $this->lastException = $exception;
    }
245063
public static function factory(RequestInterface $request, Response $response)
    {
        $message = 'Client error response' . PHP_EOL . implode(PHP_EOL, array(
            '[status code] ' . $response->getStatusCode(),
            '[reason phrase] ' . $response->getReasonPhrase(),
            '[url] ' . $request->getUrl(),
        ));

        $e = new static($message);
        $e->setResponse($response);
        $e->setRequest($request);

        return $e;
    }
1207499
protected function handleException(\Throwable $exception, RequestInterface $request): RequestException
    {
        if ($exception instanceof RequestException) {
            return $exception;
        }

        return new RequestException($request, $exception);
    }
1171008
public static function create(
        Request $request,
        Response $response = null,
        Exception $previous = null
    ) {
        if (!$response) {
            return new self('Error completing request', $request, null, $previous);
        }

        $code = $response->getStatusCode();

        switch ($code[0]) {
            case '4':
                $message = 'Client Error';
                break;
            case '5':
                $message = 'Server Error';
                break;
            default:
                $message = 'Unknown Error';
                break;
        }

        return new self($message, $request, $response, $previous);
    }
550450
public function createDbalException(Response $response, DriverExceptionInterface $exception) {
        switch ($response->getStatusCode()) {
            case Response::HTTP_BAD_REQUEST:
                return new DBALException\SyntaxErrorException($response->getContent(), $exception);

            case Response::HTTP_METHOD_NOT_ALLOWED:
            case Response::HTTP_NOT_ACCEPTABLE:
            case Response::HTTP_REQUEST_TIMEOUT:
            case Response::HTTP_LENGTH_REQUIRED:
            case Response::HTTP_INTERNAL_SERVER_ERROR:
                return new DBALException\ServerException($response->getContent(), $exception);
            
            case Response::HTTP_CONFLICT:
                return new DBALException\ConstraintViolationException($response->getContent(), $exception);

            case Response::HTTP_UNAUTHORIZED:
            case Response::HTTP_FORBIDDEN:
            case Response::HTTP_PROXY_AUTHENTICATION_REQUIRED:
            case Response::HTTP_BAD_GATEWAY:
            case Response::HTTP_SERVICE_UNAVAILABLE:
            case Response::HTTP_GATEWAY_TIMEOUT:
                return new DBALException\ConnectionException($response->getContent(), $exception);

            default:
                return new DBALException\DriverException($response->getContent(), $exception);
        }
    }
1263138
public static function wrapException(RequestInterface $request, \Exception $e)
    {
        if ($e instanceof RequestException) {
            return $e;
        } elseif ($e instanceof ConnectException) {
            return new HttpConnectException($e->getMessage(), $request, null, $e);
        } else {
            return new RequestException($e->getMessage(), $request, null, $e);
        }
    }
456586
private function createAuthenticationException(JWTDecodeFailureException $previous = null)
    {
        $message = (null === $previous) ? 'Invalid JWT Token' : $previous->getMessage();

        return new AuthenticationException($message, 401, $previous);
    }
664624
public function checkError(ResponseInterface $response)
    {
        if ($response->getStatusCode() < 400) {
            return $response;
        }

        //check if any limit was hit
        $this->checkUserRateLimit($response);
        $this->checkClientRateLimit($response);
        $this->checkPostRateLimit($response);

        $body = (string) $response->getBody();
        $responseData = json_decode($body, true);
        if (JSON_ERROR_NONE !== json_last_error()) {
            $responseData = $body;
        }

        if (\is_array($responseData) && isset($responseData['data']) && isset($responseData['data']['error'])) {
            $errorMessage = $responseData['data']['error'];
            // when uploading too fast, error is an array
            if (\is_array($responseData['data']['error'])) {
                $errorMessage = '';

                if (isset($responseData['data']['error']['message'])) {
                    $errorMessage = $responseData['data']['error']['message'];
                } elseif (isset($responseData['data']['error']['code'])) {
                    $errorMessage = 'Error code: ' . $responseData['data']['error']['code'];
                }
            }

            $message = 'Request failed with: "' . $errorMessage . '"';
            if (isset($responseData['data']['request'])) {
                $message = 'Request to: ' . $responseData['data']['request'] . ' failed with: "' . $errorMessage . '"';
            }

            throw new ErrorException($message, $response->getStatusCode());
        }

        throw new RuntimeException(\is_array($responseData) && isset($responseData['message']) ? $responseData['message'] : $responseData, $response->getStatusCode());
    }
439821
private function createStatusCodeException(
        ResponseInterface $response,
        InternalRequestInterface $internalRequest,
        HttpAdapterInterface $httpAdapter
    ) {
        $exception = HttpAdapterException::cannotFetchUri(
            (string) $internalRequest->getUri(),
            $httpAdapter->getName(),
            sprintf('Status code: %d', $response->getStatusCode())
        );

        $exception->setRequest($internalRequest);
        $exception->setResponse($response);

        return $exception;
    }
822522
public function sendRequest(Request $request)
    {
        try {
            $rawResponse = $this->processRequest($request);
        } catch (Exception $exception) {
            if ($this->successor) {
                return $this->successor->sendRequest($request);
            }
            throw $exception;
        }

        $response = new Response($request, $rawResponse);

        if ($response->isError()) {
            throw $response->getThrownException();
        }

        return $response;
    }
528045
public static function fileUnreadable(
        $fileName, 
        \Exception $previous = null
    ): self {
        return new self(
            "cannot read file: {$fileName}",
            self::FILE_UNREADABLE,
            $previous
        );
    }
1062724
protected function unauthorizedException(Request $request, Response $response, $message = 'Unauthorized.')
    {
        return new UnauthorizedException($request, $response, $message);
    }
592114
protected function createException(GuzzleRequestException $exception): RequestException
    {
        if ($exception instanceof GuzzleResponseException) {
            return new ResponseException(
                $exception->getRequest(),
                $exception->getResponse(),
                $exception
            );
        }

        throw new RequestException(
            $exception->getRequest(),
            $exception
        );
    }