Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.2.x will end 22 April 2024 (12 months).
  • Bug fixes for security issues in 4.2.x will end 7 October 2024 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.1.x is supported too.
   1  <?php
   2  
   3  namespace GuzzleHttp\Exception;
   4  
   5  use GuzzleHttp\BodySummarizer;
   6  use GuzzleHttp\BodySummarizerInterface;
   7  use Psr\Http\Client\RequestExceptionInterface;
   8  use Psr\Http\Message\RequestInterface;
   9  use Psr\Http\Message\ResponseInterface;
  10  use Psr\Http\Message\UriInterface;
  11  
  12  /**
  13   * HTTP Request exception
  14   */
  15  class RequestException extends TransferException implements RequestExceptionInterface
  16  {
  17      /**
  18       * @var RequestInterface
  19       */
  20      private $request;
  21  
  22      /**
  23       * @var ResponseInterface|null
  24       */
  25      private $response;
  26  
  27      /**
  28       * @var array
  29       */
  30      private $handlerContext;
  31  
  32      public function __construct(
  33          string $message,
  34          RequestInterface $request,
  35          ResponseInterface $response = null,
  36          \Throwable $previous = null,
  37          array $handlerContext = []
  38      ) {
  39          // Set the code of the exception if the response is set and not future.
  40          $code = $response ? $response->getStatusCode() : 0;
  41          parent::__construct($message, $code, $previous);
  42          $this->request = $request;
  43          $this->response = $response;
  44          $this->handlerContext = $handlerContext;
  45      }
  46  
  47      /**
  48       * Wrap non-RequestExceptions with a RequestException
  49       */
  50      public static function wrapException(RequestInterface $request, \Throwable $e): RequestException
  51      {
  52          return $e instanceof RequestException ? $e : new RequestException($e->getMessage(), $request, null, $e);
  53      }
  54  
  55      /**
  56       * Factory method to create a new exception with a normalized error message
  57       *
  58       * @param RequestInterface             $request        Request sent
  59       * @param ResponseInterface            $response       Response received
  60       * @param \Throwable|null              $previous       Previous exception
  61       * @param array                        $handlerContext Optional handler context
  62       * @param BodySummarizerInterface|null $bodySummarizer Optional body summarizer
  63       */
  64      public static function create(
  65          RequestInterface $request,
  66          ResponseInterface $response = null,
  67          \Throwable $previous = null,
  68          array $handlerContext = [],
  69          BodySummarizerInterface $bodySummarizer = null
  70      ): self {
  71          if (!$response) {
  72              return new self(
  73                  'Error completing request',
  74                  $request,
  75                  null,
  76                  $previous,
  77                  $handlerContext
  78              );
  79          }
  80  
  81          $level = (int) \floor($response->getStatusCode() / 100);
  82          if ($level === 4) {
  83              $label = 'Client error';
  84              $className = ClientException::class;
  85          } elseif ($level === 5) {
  86              $label = 'Server error';
  87              $className = ServerException::class;
  88          } else {
  89              $label = 'Unsuccessful request';
  90              $className = __CLASS__;
  91          }
  92  
  93          $uri = $request->getUri();
  94          $uri = static::obfuscateUri($uri);
  95  
  96          // Client Error: `GET /` resulted in a `404 Not Found` response:
  97          // <html> ... (truncated)
  98          $message = \sprintf(
  99              '%s: `%s %s` resulted in a `%s %s` response',
 100              $label,
 101              $request->getMethod(),
 102              $uri->__toString(),
 103              $response->getStatusCode(),
 104              $response->getReasonPhrase()
 105          );
 106  
 107          $summary = ($bodySummarizer ?? new BodySummarizer())->summarize($response);
 108  
 109          if ($summary !== null) {
 110              $message .= ":\n{$summary}\n";
 111          }
 112  
 113          return new $className($message, $request, $response, $previous, $handlerContext);
 114      }
 115  
 116      /**
 117       * Obfuscates URI if there is a username and a password present
 118       */
 119      private static function obfuscateUri(UriInterface $uri): UriInterface
 120      {
 121          $userInfo = $uri->getUserInfo();
 122  
 123          if (false !== ($pos = \strpos($userInfo, ':'))) {
 124              return $uri->withUserInfo(\substr($userInfo, 0, $pos), '***');
 125          }
 126  
 127          return $uri;
 128      }
 129  
 130      /**
 131       * Get the request that caused the exception
 132       */
 133      public function getRequest(): RequestInterface
 134      {
 135          return $this->request;
 136      }
 137  
 138      /**
 139       * Get the associated response
 140       */
 141      public function getResponse(): ?ResponseInterface
 142      {
 143          return $this->response;
 144      }
 145  
 146      /**
 147       * Check if a response was received
 148       */
 149      public function hasResponse(): bool
 150      {
 151          return $this->response !== null;
 152      }
 153  
 154      /**
 155       * Get contextual information about the error from the underlying handler.
 156       *
 157       * The contents of this array will vary depending on which handler you are
 158       * using. It may also be just an empty array. Relying on this data will
 159       * couple you to a specific handler, but can give more debug information
 160       * when needed.
 161       */
 162      public function getHandlerContext(): array
 163      {
 164          return $this->handlerContext;
 165      }
 166  }