diff --git a/src/Core/Enum.php b/src/Core/Enum.php index 803d4990..6d42d7b3 100644 --- a/src/Core/Enum.php +++ b/src/Core/Enum.php @@ -16,8 +16,6 @@ */ namespace Microsoft\Graph\Core; -use Microsoft\Graph\Exception\GraphException; - /** * Class Enum * @@ -41,12 +39,12 @@ abstract class Enum * * @param string $value The value of the enum * - * @throws GraphException if enum value is invalid + * @throws \InvalidArgumentException if enum value is invalid */ public function __construct($value) { if (!self::has($value)) { - throw new GraphException("Invalid enum value $value"); + throw new \InvalidArgumentException("Invalid enum value $value"); } $this->_value = $value; } diff --git a/src/Exception/BaseErrorContent.php b/src/Exception/BaseErrorContent.php new file mode 100644 index 00000000..90b7e7ba --- /dev/null +++ b/src/Exception/BaseErrorContent.php @@ -0,0 +1,55 @@ +propDict = $propDict; + } + + /** + * Returns all properties passed to the constructor + * + * @return array + */ + public function getProperties(): array { + return $this->propDict; + } + + /** + * Returns value of $property in $propDict + * + * @param $property + * @return mixed|null + */ + protected function getProperty($property) { + if (array_key_exists($property, $this->propDict)) { + return $this->propDict[$property]; + } + return null; + } +} diff --git a/src/Exception/GraphClientException.php b/src/Exception/GraphClientException.php index 02b09b7c..a0fba943 100644 --- a/src/Exception/GraphClientException.php +++ b/src/Exception/GraphClientException.php @@ -9,12 +9,15 @@ /** * Class GraphClientException + * + * Thrown when the Graph API returns 4xx responses + * * @package Microsoft\Graph\Exception * @copyright 2021 Microsoft Corporation * @license https://opensource.org/licenses/MIT MIT License * @link https://developer.microsoft.com/graph */ -class GraphClientException extends GraphException +class GraphClientException extends GraphResponseException { } diff --git a/src/Exception/GraphErrorContent.php b/src/Exception/GraphErrorContent.php new file mode 100644 index 00000000..3840f813 --- /dev/null +++ b/src/Exception/GraphErrorContent.php @@ -0,0 +1,66 @@ +getProperty("date"); + } + + /** + * Returns the client request id + * + * @return string|null + */ + public function getClientRequestId(): ?string { + return $this->getProperty("client-request-id"); + } + + /** + * Returns the request id + * + * @return string|null + */ + public function getRequestId(): ?string { + return $this->getProperty("request-id"); + } + + /** + * Returns error as a string + * + * @return string + */ + public function __toString(): string { + $errorString = ($this->getDate()) ? "Date: ".$this->getDate() : ""; + $errorString .= ($this->getClientRequestId()) ? "\nClient Request Id: ".$this->getClientRequestId() : ""; + $errorString .= ($this->getRequestId()) ? "\nRequest Id: ".$this->getRequestId() : ""; + $errorString .= ($this->getCode()) ? "\nCode: ".$this->getCode() : ""; + $errorString .= ($this->getMessage()) ? "\nMessage: ".$this->getMessage() : ""; + $errorString .= ($this->getTarget()) ? "\nTarget: ".$this->getTarget() : ""; + $errorString .= ($this->getDetails()) ? "\nDetails: ".$this->getDetails() : ""; + $errorString .= ($this->getInnerError()) ? "\nInner Error: ".$this->getInnerError() : ""; + return $errorString; + } +} diff --git a/src/Exception/GraphException.php b/src/Exception/GraphException.php deleted file mode 100644 index 61e1ce49..00000000 --- a/src/Exception/GraphException.php +++ /dev/null @@ -1,51 +0,0 @@ -code}]: {$this->message}\n"; - } -} diff --git a/src/Exception/GraphResponseException.php b/src/Exception/GraphResponseException.php new file mode 100644 index 00000000..c534e0a8 --- /dev/null +++ b/src/Exception/GraphResponseException.php @@ -0,0 +1,147 @@ +graphRequest = $graphRequest; + $this->responseStatusCode = $responseStatusCode; + $this->responseBody = $responseBody; + $this->responseHeaders = $responseHeaders; + $message = "'".$graphRequest->getRequestType()."' request to ".$graphRequest->getRequestUri()." returned ".$responseStatusCode."\n".json_encode($responseBody); + parent::__construct($message, $responseStatusCode); + } + + /** + * Returns HTTP headers in the response from the Graph + * + * @return array + */ + public function getResponseHeaders(): array { + return $this->responseHeaders; + } + + /** + * Returns HTTP status code returned int the response from the Graph + * + * @return int + */ + public function getResponseStatusCode(): int { + return $this->responseStatusCode; + } + + /** + * Get JSON-decoded response payload from the Graph + * + * @return array + */ + public function getRawResponseBody(): array { + return $this->responseBody; + } + + /** + * Returns the error object of the payload + * + * @return ODataErrorContent|null + */ + public function getError(): ?ODataErrorContent { + if (array_key_exists("error", $this->responseBody)) { + return new ODataErrorContent($this->responseBody["error"]); + } + return null; + } + + /** + * Returns the request that triggered the error response + * + * @return GraphRequest + */ + public function getRequest(): GraphRequest { + return $this->graphRequest; + } + + /** + * Returns the client request Id + * + * @return string|null + */ + public function getClientRequestId(): ?string { + $headerName = "client-request-id"; + if (array_key_exists($headerName, $this->responseHeaders) + && !empty($this->responseHeaders[$headerName])) { + return $this->responseHeaders[$headerName][0]; + } + return null; + } + + /** + * Returns the request Id + * + * @return string|null + */ + public function getRequestId(): ?string { + $headerName = "request-id"; + if (array_key_exists($headerName, $this->responseHeaders) + && !empty($this->responseHeaders[$headerName])) { + return $this->responseHeaders[$headerName][0]; + } + return null; + } +} diff --git a/src/Exception/GraphServiceException.php b/src/Exception/GraphServiceException.php new file mode 100644 index 00000000..ea2d44b8 --- /dev/null +++ b/src/Exception/GraphServiceException.php @@ -0,0 +1,24 @@ +getProperty("code"); + } + + /** + * Get error message returned by the Graph + * + * @return string|null + */ + public function getMessage(): ?string { + return $this->getProperty("message"); + } + + /** + * Returns the target of the error + * + * @return string|null + */ + public function getTarget(): ?string { + return $this->getProperty("target"); + } + + /** + * Returns the error details containing a code, message and target + * + * @return ODataErrorContent[]|null + */ + public function getDetails(): ?array { + $details = $this->getProperty("details"); + if ($details) { + return array_map(function ($detail) { return new ODataErrorContent($detail); }, $details); + } + return null; + } + + /** + * Get the Graph-specific error info + * + * @return GraphErrorContent|null + */ + public function getInnerError(): ?GraphErrorContent { + $innerError = $this->getProperty("innerError"); + return ($innerError) ? new GraphErrorContent($innerError) : null; + } + + /** + * Returns error as a string + * + * @return string + */ + public function __toString(): string { + $errorString = ($this->getCode()) ? "Code: ".$this->getCode() : ""; + $errorString .= ($this->getMessage()) ? "\nMessage: ".$this->getMessage() : ""; + $errorString .= ($this->getTarget()) ? "\nTarget: ".$this->getTarget() : ""; + $errorString .= ($this->getDetails()) ? "\nDetails: ".$this->getDetails() : ""; + $errorString .= ($this->getInnerError()) ? "\nInner Error: ".$this->getInnerError() : ""; + return $errorString; + } +} diff --git a/src/Http/AbstractGraphClient.php b/src/Http/AbstractGraphClient.php index 59a34d03..b4916025 100644 --- a/src/Http/AbstractGraphClient.php +++ b/src/Http/AbstractGraphClient.php @@ -50,7 +50,7 @@ abstract class AbstractGraphClient * * @param string|null $nationalCloud if null defaults to "https://graph.microsoft.com" * @param HttpClientInterface|null $httpClient if null creates default Guzzle client - * @throws GraphClientException + * @throws \InvalidArgumentException */ public function __construct(?string $nationalCloud = NationalCloud::GLOBAL, ?HttpClientInterface $httpClient = null) @@ -105,7 +105,7 @@ public function getHttpClient(): HttpClientInterface * * @return GraphRequest The request object, which can be used to * make queries against Graph - * @throws GraphClientException + * @throws \InvalidArgumentException */ public function createRequest(string $requestType, string $endpoint): GraphRequest { @@ -125,7 +125,7 @@ public function createRequest(string $requestType, string $endpoint): GraphReque * * @return GraphCollectionRequest The request object, which can be * used to make queries against Graph - * @throws GraphClientException + * @throws \InvalidArgumentException */ public function createCollectionRequest(string $requestType, string $endpoint): GraphCollectionRequest { diff --git a/src/Http/GraphCollectionRequest.php b/src/Http/GraphCollectionRequest.php index 991421d6..4904930b 100644 --- a/src/Http/GraphCollectionRequest.php +++ b/src/Http/GraphCollectionRequest.php @@ -10,7 +10,7 @@ use GuzzleHttp\Psr7\Uri; use Microsoft\Graph\Core\GraphConstants; use Microsoft\Graph\Exception\GraphClientException; -use Microsoft\Graph\Exception\GraphException; +use Microsoft\Graph\Exception\GraphServiceException; use Microsoft\Graph\Task\PageIterator; use Psr\Http\Client\ClientExceptionInterface; @@ -67,7 +67,7 @@ class GraphCollectionRequest extends GraphRequest * @param string $endpoint The URI of the endpoint to hit * @param AbstractGraphClient $graphClient * @param string $baseUrl (optional) If empty, it's set to $client's national cloud - * @throws GraphClientException + * @throws \InvalidArgumentException */ public function __construct(string $requestType, string $endpoint, AbstractGraphClient $graphClient, string $baseUrl = "") { @@ -84,10 +84,12 @@ public function __construct(string $requestType, string $endpoint, AbstractGraph /** * Gets the number of entries in the collection * - * @return int the number of entries - * @throws ClientExceptionInterface|GraphClientException + * @return int|null the number of entries | null if @odata.count doesn't exist for that collection + * @throws ClientExceptionInterface if an errors occurs while making the request + * @throws GraphClientException containing error payload if 4xx response is returned. + * @throws GraphServiceException containing error payload if 5xx response is returned. */ - public function count() + public function count(): ?int { $query = '$count=true'; $requestUri = $this->getRequestUri(); @@ -96,14 +98,8 @@ public function count() $this->originalReturnType = $this->returnType; $this->returnType = null; $result = $this->execute(); - - if (is_a($result, GraphResponse::class) && $result->getCount()) { - return $result->getCount(); - } - - /* The $count query parameter for the Graph API - is available on several models but not all */ - throw new GraphClientException('Count unavailable for this collection'); + $this->returnType = $this->originalReturnType; + return ($result->getCount()) ?: null; } /** @@ -111,15 +107,13 @@ public function count() * to "getPage()" * * @param int $pageSize The page size - * - * @throws GraphClientException if the requested page size exceeds - * the Graph's defined page size limit - * @return GraphCollectionRequest object + * @return GraphCollectionRequest object + * @throws \InvalidArgumentException if the requested page size exceeds Graph's defined page size limit */ public function setPageSize(int $pageSize): self { if ($pageSize > GraphConstants::MAX_PAGE_SIZE) { - throw new GraphClientException(GraphConstants::MAX_PAGE_SIZE_ERROR); + throw new \InvalidArgumentException(GraphConstants::MAX_PAGE_SIZE_ERROR); } $this->pageSize = $pageSize; return $this; @@ -129,7 +123,9 @@ public function setPageSize(int $pageSize): self * Gets the next page of results * * @return GraphResponse|array of objects of class $returnType| GraphResponse if no $returnType - * @throws ClientExceptionInterface + * @throws ClientExceptionInterface if an error occurs while making the request + * @throws GraphClientException containing error payload if 4xx response is returned. + * @throws GraphServiceException containing error payload if 5xx response is returned. */ public function getPage() { @@ -142,9 +138,9 @@ public function getPage() /** * Sets the required query information to get a new page * - * @return GraphCollectionRequest + * @return void */ - private function setPageCallInfo(): self + private function setPageCallInfo(): void { // Store these to add temporary query data to request $this->originalReturnType = $this->returnType; @@ -167,7 +163,6 @@ private function setPageCallInfo(): self $this->setRequestUri(new Uri( $requestUri . GraphRequestUtil::getQueryParamConcatenator($requestUri) . $query)); } } - return $this; } /** @@ -238,8 +233,9 @@ public function getPageSize(): int { * * @param callable(): bool $callback function to execute against each element of $entityCollection. Must return boolean which determines if iteration should pause/proceed * @return PageIterator call iterate() to start the iterator - * @throws ClientExceptionInterface - * @throws GraphClientException + * @throws ClientExceptionInterface if error occurs while making the request + * @throws GraphClientException containing error payload if 4xx is returned while fetching the initial page + * @throws GraphServiceException containing error payload if 5xx is returned while fetching the initial page */ public function pageIterator(callable $callback): PageIterator { // temporarily disable return type in order to get first page as GraphResponse object diff --git a/src/Http/GraphRequest.php b/src/Http/GraphRequest.php index 289f52f4..9fd56ab3 100644 --- a/src/Http/GraphRequest.php +++ b/src/Http/GraphRequest.php @@ -8,12 +8,14 @@ namespace Microsoft\Graph\Http; use GuzzleHttp\Psr7\Request; +use GuzzleHttp\Psr7\Response; use GuzzleHttp\Psr7\Utils; use Http\Client\HttpAsyncClient; use Http\Promise\Promise; use Microsoft\Graph\Core\GraphConstants; use Microsoft\Graph\Core\NationalCloud; use Microsoft\Graph\Exception\GraphClientException; +use Microsoft\Graph\Exception\GraphServiceException; use Psr\Http\Client\ClientExceptionInterface; use Psr\Http\Client\ClientInterface; use Psr\Http\Message\StreamInterface; @@ -87,33 +89,52 @@ class GraphRequest * @param string $endpoint The url path on the host to be called- * @param AbstractGraphClient $graphClient The Graph client to use * @param string $baseUrl (optional) If empty, it's set to $client's national cloud - * @throws GraphClientException + * @throws \InvalidArgumentException */ public function __construct(string $requestType, string $endpoint, AbstractGraphClient $graphClient, string $baseUrl = "") { if (!$requestType || !$endpoint || !$graphClient) { - throw new GraphClientException("Request type, endpoint and client cannot be null or empty"); + throw new \InvalidArgumentException("Request type, endpoint and client cannot be null or empty"); } if (!$graphClient->getAccessToken()) { - throw new GraphClientException(GraphConstants::NO_ACCESS_TOKEN); + throw new \InvalidArgumentException(GraphConstants::NO_ACCESS_TOKEN); } $this->requestType = $requestType; $this->graphClient = $graphClient; $baseUrl = ($baseUrl) ?: $graphClient->getNationalCloud(); $this->initRequestUri($baseUrl, $endpoint); - $this->initHeaders($baseUrl); + $this->initHeaders(); $this->initPsr7HttpRequest(); } + /** + * Sets the request URI and updates the Psr7 request with the new URI + * + * @param UriInterface $uri + */ protected function setRequestUri(UriInterface $uri): void { $this->requestUri = $uri; $this->httpRequest = $this->httpRequest->withUri($uri); } + /** + * Returns the final request URI after resolving $endpoint to base URL + * + * @return UriInterface + */ public function getRequestUri(): UriInterface { return $this->requestUri; } + /** + * Returns the HTTP method used + * + * @return string + */ + public function getRequestType(): string { + return $this->requestType; + } + /** * Sets a new accessToken * @@ -135,12 +156,12 @@ public function setAccessToken(string $accessToken): self * @param string $returnClass The class name to use * * @return $this object - * @throws GraphClientException when $returnClass is not an existing class + * @throws \InvalidArgumentException when $returnClass is not an existing class */ public function setReturnType(string $returnClass): self { if (!class_exists($returnClass) && !interface_exists($returnClass)) { - throw new GraphClientException("Return type specified does not match an existing class definition"); + throw new \InvalidArgumentException("Return type specified does not match an existing class definition"); } $this->returnType = $returnClass; $this->returnsStream = ($returnClass === StreamInterface::class); @@ -153,12 +174,12 @@ public function setReturnType(string $returnClass): self * @param array $headers An array of custom headers * * @return GraphRequest object - * @throws GraphClientException if attempting to overwrite SdkVersion header + * @throws \InvalidArgumentException if attempting to overwrite SdkVersion header */ public function addHeaders(array $headers): self { if (array_key_exists("SdkVersion", $headers)) { - throw new GraphClientException("Cannot overwrite SdkVersion header"); + throw new \InvalidArgumentException("Cannot overwrite SdkVersion header"); } // Recursive merge to support appending values to multi-value headers $this->headers = array_merge_recursive($this->headers, $headers); @@ -213,7 +234,9 @@ public function getBody() * * @param ClientInterface|null $client (optional) When null, uses $graphClient's http client * @return array|GraphResponse|StreamInterface|object Graph Response object or response body cast to $returnType - * @throws ClientExceptionInterface + * @throws ClientExceptionInterface if an error occurs while making the request + * @throws GraphClientException containing error payload if 4xx response is returned. + * @throws GraphServiceException containing error payload if 5xx response is returned. */ public function execute(?ClientInterface $client = null) { @@ -222,6 +245,7 @@ public function execute(?ClientInterface $client = null) } $result = $client->sendRequest($this->httpRequest); + $this->handleErrorResponse($result); // Check to see if returnType is a stream, if so return it immediately if($this->returnsStream) { @@ -250,7 +274,10 @@ public function execute(?ClientInterface $client = null) * * @param HttpAsyncClient|null $client (optional) When null, uses $graphClient's http client * @return Promise Resolves to GraphResponse object|response body cast to $returnType. Fails throwing the exception - * @throws \Exception when promise fails + * @throws ClientExceptionInterface if there are any errors while making the HTTP request + * @throws GraphClientException containing error payload if 4xx is returned + * @throws GraphServiceException containing error payload if 5xx is returned + * @throws \Exception */ public function executeAsync(?HttpAsyncClient $client = null): Promise { @@ -261,6 +288,7 @@ public function executeAsync(?HttpAsyncClient $client = null): Promise return $client->sendAsyncRequest($this->httpRequest)->then( // On success, return the result/response function ($result) { + $this->handleErrorResponse($result); // Check to see if returnType is a stream, if so return it immediately if($this->returnsStream) { @@ -293,22 +321,23 @@ function ($reason) { * * @param string $path path to download the file contents to * @param ClientInterface|null $client (optional) When null, defaults to $graphClient's http client - * @throws ClientExceptionInterface|GraphClientException when unable to open $path for writing + * @throws \RuntimeException when unable to open $path for writing + * @throws ClientExceptionInterface if an error occurs while making the request + * @throws GraphClientException containing error payload if 4xx is returned + * @throws GraphServiceException containing error payload if 5xx is returned */ public function download(string $path, ?ClientInterface $client = null): void { if (is_null($client)) { $client = $this->graphClient->getHttpClient(); } - try { - $resource = Utils::tryFopen($path, 'w'); - $stream = Utils::streamFor($resource); - $response = $client->sendRequest($this->httpRequest); - $stream->write($response->getBody()->getContents()); - $stream->close(); - } catch (\RuntimeException $ex) { - throw new GraphClientException(GraphConstants::INVALID_FILE, $ex->getCode(), $ex); - } + + $resource = Utils::tryFopen($path, 'w'); + $stream = Utils::streamFor($resource); + $response = $client->sendRequest($this->httpRequest); + $this->handleErrorResponse($response); + $stream->write($response->getBody()->getContents()); + $stream->close(); } /** @@ -317,27 +346,26 @@ public function download(string $path, ?ClientInterface $client = null): void * @param string $path path of file to be uploaded * @param ClientInterface|null $client (optional) * @return array|GraphResponse|StreamInterface|object Graph Response object or response body cast to $returnType - * @throws ClientExceptionInterface|GraphClientException if $path cannot be opened for reading + * @throws ClientExceptionInterface if an error occurs while making the request + * @throws \RuntimeException if $path cannot be opened for reading + * @throws GraphClientException containing error payload if 4xx is returned + * @throws GraphServiceException containing error payload if 5xx is returned */ public function upload(string $path, ?ClientInterface $client = null) { if (is_null($client)) { $client = $this->graphClient->getHttpClient(); } - try { - $resource = Utils::tryFopen($path, 'r'); - $stream = Utils::streamFor($resource); - $this->attachBody($stream); - return $this->execute($client); - } catch(\RuntimeException $e) { - throw new GraphClientException(GraphConstants::INVALID_FILE, $e->getCode(), $e->getPrevious()); - } + $resource = Utils::tryFopen($path, 'r'); + $stream = Utils::streamFor($resource); + $this->attachBody($stream); + return $this->execute($client); } /** * Sets default headers based on baseUrl being a Graph endpoint or not */ - private function initHeaders(string $baseUrl): void + private function initHeaders(): void { $coreSdkVersion = "graph-php-core/".GraphConstants::SDK_VERSION; if ($this->graphClient->getApiVersion() === GraphConstants::BETA_API_VERSION) { @@ -363,17 +391,62 @@ private function initHeaders(string $baseUrl): void * * @param string $baseUrl * @param string $endpoint - * @throws GraphClientException + * @throws \InvalidArgumentException */ protected function initRequestUri(string $baseUrl, string $endpoint): void { - try { - $this->requestUri = GraphRequestUtil::getRequestUri($baseUrl, $endpoint, $this->graphClient->getApiVersion()); - } catch (\InvalidArgumentException $ex) { - throw new GraphClientException($ex->getMessage(), 0, $ex); - } + $this->requestUri = GraphRequestUtil::getRequestUri($baseUrl, $endpoint, $this->graphClient->getApiVersion()); } + /** + * Initialises a PSR-7 Http Request object + */ protected function initPsr7HttpRequest(): void { $this->httpRequest = new Request($this->requestType, $this->requestUri, $this->headers, $this->requestBody); } + + /** + * Check if response status code is a client error + * + * @param int $httpStatusCode + * @return bool + */ + private function is4xx(int $httpStatusCode): bool { + return ($httpStatusCode >= 400 && $httpStatusCode < 500); + } + + /** + * Check if response status code is a server error + * + * @param int $httpStatusCode + * @return bool + */ + private function is5xx(int $httpStatusCode): bool { + return ($httpStatusCode >= 500 && $httpStatusCode < 600); + } + + /** + * Throws appropriate exception type + * + * @param Response $httpResponse + * @throws GraphServiceException for server errors + * @throws GraphClientException for client errors + */ + private function handleErrorResponse(Response $httpResponse) { + if ($this->is5xx($httpResponse->getStatusCode())) { + throw new GraphServiceException( + $this, + $httpResponse->getStatusCode(), + json_decode($httpResponse->getBody(), true), + $httpResponse->getHeaders() + ); + } + if ($this->is4xx($httpResponse->getStatusCode())) { + throw new GraphClientException( + $this, + $httpResponse->getStatusCode(), + json_decode($httpResponse->getBody(), true), + $httpResponse->getHeaders() + ); + } + } } diff --git a/src/Http/HttpClientFactory.php b/src/Http/HttpClientFactory.php index 37bbd81e..ee5d38b1 100644 --- a/src/Http/HttpClientFactory.php +++ b/src/Http/HttpClientFactory.php @@ -75,11 +75,11 @@ private static function getInstance(): HttpClientFactory { * * @param string $nationalCloud * @return $this - * @throws GraphClientException if $nationalCloud is empty or an invalid national cloud Host + * @throws \InvalidArgumentException if $nationalCloud is empty or an invalid national cloud Host */ public static function setNationalCloud(string $nationalCloud = NationalCloud::GLOBAL): HttpClientFactory { if (!$nationalCloud || !NationalCloud::containsNationalCloudHost($nationalCloud)) { - throw new GraphClientException("Invalid national cloud passed. See https://docs.microsoft.com/en-us/graph/deployments#microsoft-graph-and-graph-explorer-service-root-endpoints."); + throw new \InvalidArgumentException("Invalid national cloud passed. See https://docs.microsoft.com/en-us/graph/deployments#microsoft-graph-and-graph-explorer-service-root-endpoints."); } self::$nationalCloud = $nationalCloud; return self::getInstance(); diff --git a/src/Task/PageIterator.php b/src/Task/PageIterator.php index ed6609c6..ac4a3e56 100644 --- a/src/Task/PageIterator.php +++ b/src/Task/PageIterator.php @@ -11,6 +11,7 @@ use Http\Promise\FulfilledPromise; use Http\Promise\Promise; use Microsoft\Graph\Exception\GraphClientException; +use Microsoft\Graph\Exception\GraphServiceException; use Microsoft\Graph\Http\AbstractGraphClient; use Microsoft\Graph\Http\GraphResponse; use Microsoft\Graph\Http\RequestOptions; @@ -90,7 +91,7 @@ class PageIterator * if empty, each entity will be JSON-decoded to an array and passed to $callback * @param RequestOptions|null $requestOptions (optional) custom headers/middleware to use for subsequent calls to $entityCollection's nextLink * - * @throws GraphClientException if GraphResponse does not contain a collection of values + * @throws \InvalidArgumentException if GraphResponse does not contain a collection of values */ public function __construct(AbstractGraphClient $graphClient, GraphResponse $collectionResponse, @@ -100,7 +101,7 @@ public function __construct(AbstractGraphClient $graphClient, if (!array_key_exists("value", $collectionResponse->getBody()) || !is_array($collectionResponse->getBody()["value"])) { - throw new GraphClientException("Collection response must contain a collection of values"); + throw new \InvalidArgumentException("Collection response must contain a collection of values"); } $this->graphClient = $graphClient; @@ -117,7 +118,9 @@ public function __construct(AbstractGraphClient $graphClient, * * @return Promise that resolves to true on completion and throws error on rejection * - * @throws \Exception if promise is rejected + * @throws ClientExceptionInterface if error occurs while making the request + * @throws GraphClientException containing error payload if 4xx is returned + * @throws GraphServiceException containing error payload if 5xx is returned */ public function iterate(): Promise { $promise = new FulfilledPromise(false); @@ -155,7 +158,9 @@ public function iterate(): Promise { * Resume iteration after $callback returning false * * @return Promise - * @throws \Exception if promise is rejected + * @throws ClientExceptionInterface if error occurs while making the request + * @throws GraphClientException containing error payload if 4xx is returned + * @throws GraphServiceException containing error payload if 5xx is returned */ public function resume(): Promise { return $this->iterate(); @@ -204,8 +209,9 @@ public function getNextLink(): ?string { /** * Fetches the next page of results * - * @throws GraphClientException - * @throws ClientExceptionInterface + * @throws ClientExceptionInterface if error occurs while making the request + * @throws GraphClientException containing error payload if 4xx is returned + * @throws GraphServiceException containing error payload if 5xx is returned */ private function getNextPage(): void { $nextLink = $this->getNextLink(); @@ -214,7 +220,7 @@ private function getNextPage(): void { $request = $request->addHeaders($this->requestOptions->getHeaders()); } $this->collectionResponse = $request->execute(); - if (!$this->collectionResponse || empty($this->collectionResponse->getBody())) { + if (!$this->collectionResponse || empty($this->collectionResponse->getBody()) || !array_key_exists("value", $this->collectionResponse->getBody())) { $this->entityCollection = []; return; } @@ -223,7 +229,6 @@ private function getNextPage(): void { $this->entityCollection = $this->collectionResponse->getBody()["value"]; return; } - throw new GraphClientException("No 'value' attribute found in payload after requesting ".$nextLink); } $this->entityCollection = $this->collectionResponse->getResponseAsObject($this->returnType); } diff --git a/tests/Exception/ErrorContentTest.php b/tests/Exception/ErrorContentTest.php new file mode 100644 index 00000000..0bb6ca9b --- /dev/null +++ b/tests/Exception/ErrorContentTest.php @@ -0,0 +1,37 @@ +rawErrorContent = SampleGraphResponsePayload::ERROR_PAYLOAD["error"]; + $this->odataErrorContent = new ODataErrorContent($this->rawErrorContent); + parent::setUp(); + } + + public function testGetters(): void { + $this->assertEquals($this->rawErrorContent["code"], $this->odataErrorContent->getCode()); + $this->assertEquals($this->rawErrorContent["message"], $this->odataErrorContent->getMessage()); + $this->assertNull($this->odataErrorContent->getTarget()); + $this->assertNull($this->odataErrorContent->getDetails()); + $this->assertInstanceOf(GraphErrorContent::class, $this->odataErrorContent->getInnerError()); + $this->assertNotEmpty($this->odataErrorContent->getProperties()); + $this->assertNotEmpty(strval($this->odataErrorContent)); + } +} diff --git a/tests/Exception/GraphExceptionTest.php b/tests/Exception/GraphExceptionTest.php deleted file mode 100644 index 2d333650..00000000 --- a/tests/Exception/GraphExceptionTest.php +++ /dev/null @@ -1,21 +0,0 @@ -assertEquals("Microsoft\Graph\Exception\GraphException: [404]: bad stuff\n", $exception->__toString()); - } - - public function testChildExceptionClassToString() { - $exception = new GraphClientException("Invalid national cloud"); - $this->assertStringContainsString(get_class($exception), $exception); - } -} diff --git a/tests/Exception/GraphResponseExceptionTest.php b/tests/Exception/GraphResponseExceptionTest.php new file mode 100644 index 00000000..4cc3a6ed --- /dev/null +++ b/tests/Exception/GraphResponseExceptionTest.php @@ -0,0 +1,75 @@ + "application/json", + "request-id" => "2f91ee0a-e013-425b-a5bf-b1f251163969", + "client-request-id" => "2f91ee0a-e013-425b-a5bf-b1f251163969", + ]; + private $defaultException; + private $psr7Response; + + protected function setUp(): void { + $this->mockGraphRequest = $this->createMock(GraphRequest::class); + $this->psr7Response = new Response($this->responseStatusCode, $this->responseHeaders, json_encode($this->responseBody)); + $this->defaultException = new GraphResponseException( + $this->mockGraphRequest, + $this->psr7Response->getStatusCode(), + json_decode($this->psr7Response->getBody(), true), + $this->psr7Response->getHeaders() + ); + } + + public function testGraphResponseExceptionIsThrowable(): void { + $this->assertInstanceOf(\Throwable::class, $this->defaultException); + } + + public function testGetters(): void { + $this->assertEquals($this->mockGraphRequest, $this->defaultException->getRequest()); + $this->assertEquals($this->responseStatusCode, $this->defaultException->getResponseStatusCode()); + $this->assertEquals($this->responseBody, $this->defaultException->getRawResponseBody()); + $this->assertEquals($this->psr7Response->getHeaders(), $this->defaultException->getResponseHeaders()); + $this->assertInstanceOf(ODataErrorContent::class, $this->defaultException->getError()); + } + + public function testGetClientRequestId(): void { + $headerName = "client-request-id"; + $this->assertEquals( + $this->responseHeaders[$headerName], + $this->defaultException->getClientRequestId() + ); + unset($this->responseHeaders[$headerName]); + $this->setUp(); + $this->assertNull($this->defaultException->getClientRequestId()); + } + + public function testGetRequestId(): void { + $headerName = "request-id"; + $this->assertEquals( + $this->responseHeaders[$headerName], + $this->defaultException->getRequestId() + ); + unset($this->responseHeaders[$headerName]); + $this->setUp(); + $this->assertNull($this->defaultException->getRequestId()); + } +} diff --git a/tests/Http/AbstractGraphClientTest.php b/tests/Http/AbstractGraphClientTest.php index e7d7f0ae..c59b3b19 100644 --- a/tests/Http/AbstractGraphClientTest.php +++ b/tests/Http/AbstractGraphClientTest.php @@ -41,7 +41,7 @@ public function testConstructorWithNullParams() { } public function testConstructorWithInvalidNationalCloud() { - $this->expectException(GraphClientException::class); + $this->expectException(\InvalidArgumentException::class); $graphClient = $this->getMockBuilder(AbstractGraphClient::class) ->setConstructorArgs(["https://www.microsoft.com", null]) ->getMockForAbstractClass(); @@ -61,12 +61,12 @@ public function testCreateRequestReturnsGraphRequest() { } public function testCreateRequestWithoutSettingAccessTokenThrowsException() { - $this->expectException(GraphClientException::class); + $this->expectException(\InvalidArgumentException::class); $request = $this->defaultGraphClient->createRequest("GET", "/"); } public function testCreateRequestWithInvalidParamsThrowsException() { - $this->expectException(GraphClientException::class); + $this->expectException(\InvalidArgumentException::class); $this->defaultGraphClient->createRequest("", ""); } @@ -77,12 +77,12 @@ public function testCreateCollectionRequestReturnsGraphCollectionRequest() { } public function testCreateCollectionRequestWithoutAccessTokenThrowsException() { - $this->expectException(GraphClientException::class); + $this->expectException(\InvalidArgumentException::class); $request = $this->defaultGraphClient->createCollectionRequest("GET", "/me/users"); } public function testCreateCollectionRequestWithInvalidParamsThrowsException() { - $this->expectException(GraphClientException::class); + $this->expectException(\InvalidArgumentException::class); $this->defaultGraphClient->createCollectionRequest("", ""); } } diff --git a/tests/Http/HttpClientFactoryTest.php b/tests/Http/HttpClientFactoryTest.php index 9af63608..4803dbbb 100644 --- a/tests/Http/HttpClientFactoryTest.php +++ b/tests/Http/HttpClientFactoryTest.php @@ -12,12 +12,12 @@ class HttpClientFactoryTest extends \PHPUnit\Framework\TestCase { function testNationalCloudWithEmptyString() { - $this->expectException(GraphClientException::class); + $this->expectException(\InvalidArgumentException::class); HttpClientFactory::setNationalCloud(""); } function testNationalCloudWithInvalidUrl() { - $this->expectException(GraphClientException::class); + $this->expectException(\InvalidArgumentException::class); HttpClientFactory::setNationalCloud("https://www.microsoft.com"); } diff --git a/tests/Http/Request/GraphCollectionRequestTest.php b/tests/Http/Request/GraphCollectionRequestTest.php index 9bba4d33..381bdc37 100644 --- a/tests/Http/Request/GraphCollectionRequestTest.php +++ b/tests/Http/Request/GraphCollectionRequestTest.php @@ -3,7 +3,7 @@ use Microsoft\Graph\Core\GraphConstants; use Microsoft\Graph\Exception\GraphClientException; -use Microsoft\Graph\Exception\GraphException; +use Microsoft\Graph\Exception\GraphServiceException; use Microsoft\Graph\Http\GraphCollectionRequest; use Microsoft\Graph\Http\GraphRequestUtil; use Microsoft\Graph\Task\PageIterator; @@ -29,7 +29,7 @@ public function testSetPageSizeReturnsInstance(): void { } public function testSetPageSizeExceedingMaxSizeThrowsException(): void { - $this->expectException(GraphClientException::class); + $this->expectException(\InvalidArgumentException::class); $this->defaultCollectionRequest->setPageSize(GraphConstants::MAX_PAGE_SIZE + 1); } @@ -61,16 +61,39 @@ public function testHitEndOfCollection() $this->defaultCollectionRequest->getPage(); } + public function testGetPageThrowsExceptionOn5xxResponse(): void { + $this->expectException(GraphServiceException::class); + MockHttpClientResponseConfig::configureWithErrorPayload($this->mockHttpClient, 500); + $this->defaultCollectionRequest->getPage(); + } + + public function testGetPageThrowsExceptionOn4xxResponse(): void { + $this->expectException(GraphClientException::class); + MockHttpClientResponseConfig::configureWithErrorPayload($this->mockHttpClient, 400); + $this->defaultCollectionRequest->getPage(); + } + public function testCount(): void { MockHttpClientResponseConfig::configureWithCollectionPayload($this->mockHttpClient); $count = $this->defaultCollectionRequest->count(); $this->assertEquals(SampleGraphResponsePayload::COLLECTION_PAYLOAD["@odata.count"], $count); } - public function testCountThrowsErrorIfNoOdataCountFound(): void { - $this->expectException(GraphException::class); + public function testCountReturnsNullIfNoOdataCountFound(): void { MockHttpClientResponseConfig::configureWithEmptyPayload($this->mockHttpClient); - $count = $this->defaultCollectionRequest->count(); + $this->assertNull($this->defaultCollectionRequest->count()); + } + + public function testCountThrowsExceptionOn5xxResponse(): void { + $this->expectException(GraphServiceException::class); + MockHttpClientResponseConfig::configureWithErrorPayload($this->mockHttpClient, 503); + $this->defaultCollectionRequest->count(); + } + + public function testCountThrowsExceptionOn4xxResponse(): void { + $this->expectException(GraphClientException::class); + MockHttpClientResponseConfig::configureWithErrorPayload($this->mockHttpClient, 404); + $this->defaultCollectionRequest->count(); } public function testPageIteratorReturnsValidPageIterator() { @@ -96,4 +119,16 @@ public function testPageIteratorInitialisesUsingFirstPageOfResults() { $promise->wait(); $this->assertTrue($numEntitiesProcessed >= sizeof(SampleGraphResponsePayload::COLLECTION_PAYLOAD["value"])); } + + public function testPageIteratorThrowsExceptionIfFirstPageRequestGets5xxResponse(): void { + $this->expectException(GraphServiceException::class); + MockHttpClientResponseConfig::configureWithErrorPayload($this->mockHttpClient, 500); + $this->defaultCollectionRequest->pageIterator(function () {}); + } + + public function testPageIteratorThrowsExceptionIfFirstPageRequestGets4xxResponse(): void { + $this->expectException(GraphClientException::class); + MockHttpClientResponseConfig::configureWithErrorPayload($this->mockHttpClient, 400); + $this->defaultCollectionRequest->pageIterator(function () {}); + } } diff --git a/tests/Http/Request/GraphRequestAsyncTest.php b/tests/Http/Request/GraphRequestAsyncTest.php index 47ea2e2b..24e7d309 100644 --- a/tests/Http/Request/GraphRequestAsyncTest.php +++ b/tests/Http/Request/GraphRequestAsyncTest.php @@ -9,12 +9,12 @@ namespace Microsoft\Graph\Test\Http\Request; -use GuzzleHttp\Psr7\Stream; use Http\Client\HttpAsyncClient; use Http\Promise\Promise; +use Microsoft\Graph\Exception\GraphClientException; +use Microsoft\Graph\Exception\GraphServiceException; use Microsoft\Graph\Http\GraphResponse; use Microsoft\Graph\Test\Http\SampleGraphResponsePayload; -use Microsoft\Graph\Test\Http\TestModel; use Microsoft\Graph\Test\TestData\Model\User; use Psr\Http\Client\ClientExceptionInterface; use Psr\Http\Client\NetworkExceptionInterface; @@ -62,17 +62,28 @@ public function testExecuteAsyncPromiseResolvesToGraphResponseIfNoReturnType(): $this->assertInstanceOf(GraphResponse::class, $promise->wait()); } - public function testExecuteAsyncPromiseResolvesToGraphResponseForErrorPayload(): void { + public function testExecuteAsyncPromiseThrowsExceptionFor4xxResponse(): void { + $this->expectException(GraphClientException::class); MockHttpClientAsyncResponseConfig::statusCode(400)::configureWithFulfilledPromise( $this->mockHttpClient, SampleGraphResponsePayload::ERROR_PAYLOAD ); $promise = $this->defaultGraphRequest->executeAsync(); - $this->assertInstanceOf(GraphResponse::class, $promise->wait()); + $promise->wait(); + } + + public function testExecuteAsyncPromiseThrowsExceptionFor5xxResponse(): void { + $this->expectException(GraphServiceException::class); + MockHttpClientAsyncResponseConfig::statusCode(500)::configureWithFulfilledPromise( + $this->mockHttpClient, + SampleGraphResponsePayload::ERROR_PAYLOAD + ); + $promise = $this->defaultGraphRequest->executeAsync(); + $promise->wait(); } public function testExecuteAsyncResolvesToModelForModelReturnType(): void { - MockHttpClientAsyncResponseConfig::configureWithFulfilledPromise( + MockHttpClientAsyncResponseConfig::statusCode()::configureWithFulfilledPromise( $this->mockHttpClient, SampleGraphResponsePayload::ENTITY_PAYLOAD ); @@ -81,7 +92,7 @@ public function testExecuteAsyncResolvesToModelForModelReturnType(): void { } public function testExecuteAsyncResolvesToModelArrayForCollectionRequest(): void { - MockHttpClientAsyncResponseConfig::configureWithFulfilledPromise( + MockHttpClientAsyncResponseConfig::statusCode()::configureWithFulfilledPromise( $this->mockHttpClient, SampleGraphResponsePayload::COLLECTION_PAYLOAD ); diff --git a/tests/Http/Request/GraphRequestStreamTest.php b/tests/Http/Request/GraphRequestStreamTest.php index e2952a7b..777db3fb 100644 --- a/tests/Http/Request/GraphRequestStreamTest.php +++ b/tests/Http/Request/GraphRequestStreamTest.php @@ -3,6 +3,7 @@ namespace Microsoft\Graph\Test\Http\Request; use Microsoft\Graph\Exception\GraphClientException; +use Microsoft\Graph\Exception\GraphServiceException; use Microsoft\Graph\Test\Http\SampleGraphResponsePayload; use org\bovigo\vfs\vfsStream; use org\bovigo\vfs\vfsStreamFile; @@ -29,12 +30,32 @@ public function testUpload() public function testInvalidUpload() { - $this->expectException(GraphClientException::class); + $this->expectException(\RuntimeException::class); $file = new VfsStreamFile('foo.txt', 0000); $this->rootDir->addChild($file); $this->defaultGraphRequest->upload($file->url()); } + public function testUploadThrowsExceptionFor4xxResponse() + { + $this->expectException(GraphClientException::class); + MockHttpClientResponseConfig::configureWithErrorPayload($this->mockHttpClient, 400); + $file = vfsStream::newFile('foo.txt') + ->withContent("content") + ->at($this->rootDir); + $this->defaultGraphRequest->upload($file->url()); + } + + public function testUploadThrowsExceptionFor5xxResponse() + { + $this->expectException(GraphServiceException::class); + MockHttpClientResponseConfig::configureWithErrorPayload($this->mockHttpClient, 500); + $file = vfsStream::newFile('foo.txt') + ->withContent("content") + ->at($this->rootDir); + $this->defaultGraphRequest->upload($file->url()); + } + public function testDownload() { $file = new VfsStreamFile('foo.txt'); @@ -47,9 +68,27 @@ public function testDownload() public function testInvalidDownload() { - $this->expectException(GraphClientException::class); + $this->expectException(\RuntimeException::class); $file = new VfsStreamFile('foo.txt', 0000); $this->rootDir->addChild($file); $this->defaultGraphRequest->download($file->url()); } + + public function testDownloadThrowsExceptionFor4xxResponse() + { + $this->expectException(GraphClientException::class); + MockHttpClientResponseConfig::configureWithErrorPayload($this->mockHttpClient, 400); + $file = new VfsStreamFile('foo.txt'); + $this->rootDir->addChild($file); + $this->defaultGraphRequest->download($file->url()); + } + + public function testDownloadThrowsExceptionFor5xxResponse() + { + $this->expectException(GraphServiceException::class); + MockHttpClientResponseConfig::configureWithErrorPayload($this->mockHttpClient, 500); + $file = new VfsStreamFile('foo.txt'); + $this->rootDir->addChild($file); + $this->defaultGraphRequest->download($file->url()); + } } diff --git a/tests/Http/Request/GraphRequestSyncTest.php b/tests/Http/Request/GraphRequestSyncTest.php index 9f5be8b2..556cba3e 100644 --- a/tests/Http/Request/GraphRequestSyncTest.php +++ b/tests/Http/Request/GraphRequestSyncTest.php @@ -9,9 +9,9 @@ namespace Microsoft\Graph\Test\Http\Request; -use GuzzleHttp\Psr7\Stream; +use Microsoft\Graph\Exception\GraphClientException; +use Microsoft\Graph\Exception\GraphServiceException; use Microsoft\Graph\Http\GraphResponse; -use Microsoft\Graph\Test\Http\TestModel; use Microsoft\Graph\Test\TestData\Model\User; use Psr\Http\Client\ClientExceptionInterface; use Psr\Http\Client\ClientInterface; @@ -54,10 +54,16 @@ public function testExecuteWithoutReturnTypeReturnsGraphResponseForEmptyPayload( $this->assertInstanceOf(GraphResponse::class, $response); } - public function testExecuteWithoutReturnTypeReturnsGraphResponseForErrorPayload(): void { - MockHttpClientResponseConfig::configureWithErrorPayload($this->mockHttpClient); + public function testExecuteWithoutReturnTypeThrowsExceptionFor4xxPayload(): void { + $this->expectException(GraphClientException::class); + MockHttpClientResponseConfig::configureWithErrorPayload($this->mockHttpClient, 400); + $response = $this->defaultGraphRequest->execute(); + } + + public function testExecuteWithoutReturnTypeThrowsExceptionFor5xxPayload(): void { + $this->expectException(GraphServiceException::class); + MockHttpClientResponseConfig::configureWithErrorPayload($this->mockHttpClient, 500); $response = $this->defaultGraphRequest->execute(); - $this->assertInstanceOf(GraphResponse::class, $response); } public function testExecuteWithoutReturnTypeReturnsGraphResponseForStreamPayload(): void { @@ -84,10 +90,16 @@ public function testExecuteWithModelReturnTypeReturnsModelForEmptyPayload(): voi $this->assertInstanceOf(User::class, $response); } - public function testExecuteWithModelReturnTypeReturnsModelForErrorPayload(): void { - MockHttpClientResponseConfig::configureWithErrorPayload($this->mockHttpClient); + public function testExecuteWithModelReturnTypeThrowsExceptionFor4xxPayload(): void { + $this->expectException(GraphClientException::class); + MockHttpClientResponseConfig::configureWithErrorPayload($this->mockHttpClient, 400); + $response = $this->defaultGraphRequest->setReturnType(User::class)->execute(); + } + + public function testExecuteWithModelReturnTypeThrowsExceptionFor5xxPayload(): void { + $this->expectException(GraphServiceException::class); + MockHttpClientResponseConfig::configureWithErrorPayload($this->mockHttpClient, 500); $response = $this->defaultGraphRequest->setReturnType(User::class)->execute(); - $this->assertInstanceOf(User::class, $response); } public function testExecuteWithModelReturnTypeReturnsModelForStreamPayload(): void { @@ -116,10 +128,16 @@ public function testExecuteWithStreamReturnTypeReturnsStreamForEmptyPayload(): v $this->assertInstanceOf(StreamInterface::class, $response); } - public function testExecuteWithStreamReturnTypeReturnsStreamForErrorPayload(): void { - MockHttpClientResponseConfig::configureWithErrorPayload($this->mockHttpClient); + public function testExecuteWithStreamReturnTypeThrowsExceptionFor4xxPayload(): void { + $this->expectException(GraphClientException::class); + MockHttpClientResponseConfig::configureWithErrorPayload($this->mockHttpClient, 400); + $response = $this->defaultGraphRequest->setReturnType(StreamInterface::class)->execute(); + } + + public function testExecuteWithStreamReturnTypeThrowsExceptionFor5xxPayload(): void { + $this->expectException(GraphServiceException::class); + MockHttpClientResponseConfig::configureWithErrorPayload($this->mockHttpClient, 500); $response = $this->defaultGraphRequest->setReturnType(StreamInterface::class)->execute(); - $this->assertInstanceOf(StreamInterface::class, $response); } public function testExecuteWithStreamReturnTypeReturnsStreamForStreamPayload(): void { diff --git a/tests/Http/Request/GraphRequestTest.php b/tests/Http/Request/GraphRequestTest.php index dfd91e57..7fc15fc3 100644 --- a/tests/Http/Request/GraphRequestTest.php +++ b/tests/Http/Request/GraphRequestTest.php @@ -4,10 +4,8 @@ use Microsoft\Graph\Core\GraphConstants; use Microsoft\Graph\Core\NationalCloud; -use Microsoft\Graph\Exception\GraphClientException; use Microsoft\Graph\Http\AbstractGraphClient; use Microsoft\Graph\Http\GraphRequest; -use Microsoft\Graph\Test\Http\TestModel; use Microsoft\Graph\Test\TestData\Model\User; class GraphRequestTest extends BaseGraphRequestTest @@ -18,18 +16,18 @@ public function testConstructorWithNullParametersThrowsException(): void { } public function testConstructorWithEmptyParametersThrowsException(): void { - $this->expectException(GraphClientException::class); + $this->expectException(\InvalidArgumentException::class); $request = new GraphRequest("", "", $this->mockGraphClient); } public function testConstructorWithoutAccessTokenThrowsException(): void { $graphClient = $this->getMockForAbstractClass(AbstractGraphClient::class); - $this->expectException(GraphClientException::class); + $this->expectException(\InvalidArgumentException::class); $request = new GraphRequest("GET", "/me", $graphClient); } public function testConstructorWithInvalidCustomBaseUrlThrowsException(): void { - $this->expectException(GraphClientException::class); + $this->expectException(\InvalidArgumentException::class); $baseUrl = "www.outlook.com"; # no scheme $request = new GraphRequest("GET", "/me", $this->mockGraphClient, $baseUrl); } @@ -162,7 +160,7 @@ public function testSetReturnTypeReturnsGraphRequestInstance(): void { } public function testSetReturnTypeWithInvalidClassThrowsException(): void { - $this->expectException(GraphClientException::class); + $this->expectException(\InvalidArgumentException::class); $this->defaultGraphRequest->setReturnType("Model\User"); } @@ -175,7 +173,7 @@ public function testAddHeadersReturnsGraphRequestInstance(): void { } public function testAddHeadersCannotAppendOrOverwriteSdkVersionValue(): void { - $this->expectException(GraphClientException::class); + $this->expectException(\InvalidArgumentException::class); $this->defaultGraphRequest->addHeaders([ 'SdkVersion' => 'Version1', 'Content-Encoding' => 'gzip' diff --git a/tests/Task/PageIteratorTest.php b/tests/Task/PageIteratorTest.php index 4e4bd2d2..dfe5b426 100644 --- a/tests/Task/PageIteratorTest.php +++ b/tests/Task/PageIteratorTest.php @@ -10,8 +10,6 @@ use GuzzleHttp\Psr7\Utils; -use Microsoft\Graph\Exception\GraphClientException; -use Microsoft\Graph\Http\AbstractGraphClient; use Microsoft\Graph\Http\GraphCollectionRequest; use Microsoft\Graph\Http\GraphResponse; use Microsoft\Graph\Http\RequestOptions; @@ -75,7 +73,7 @@ public function testConstructorCreatesPageIterator() { } public function testConstructorThrowsExceptionIfGraphResponseIsNotACollection() { - $this->expectException(GraphClientException::class); + $this->expectException(\InvalidArgumentException::class); $pageIterator = new PageIterator( $this->mockGraphClient, $this->createCollectionResponse(SampleGraphResponsePayload::ENTITY_PAYLOAD),