Skip to content

Commit 49486a8

Browse files
sivaschenkoacrobat
authored andcommitted
Corrected error handling in case of 502 GitHub response (#759)
* #759: Corrected error handling in case of 502 GitHub response * Covered GithubExceptionThrower with a unit test * Fixed code style * Adjusted test for PHP 5.6 - PHPUnit 6.5
1 parent 21d93ad commit 49486a8

File tree

2 files changed

+160
-0
lines changed

2 files changed

+160
-0
lines changed

lib/Github/HttpClient/Plugin/GithubExceptionThrower.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,17 @@ public function handleRequest(RequestInterface $request, callable $next, callabl
8484
}
8585
}
8686

87+
if (502 == $response->getStatusCode() && isset($content['errors']) && is_array($content['errors'])) {
88+
$errors = [];
89+
foreach ($content['errors'] as $error) {
90+
if (isset($error['message'])) {
91+
$errors[] = $error['message'];
92+
}
93+
}
94+
95+
throw new RuntimeException(implode(', ', $errors), 502);
96+
}
97+
8798
throw new RuntimeException(isset($content['message']) ? $content['message'] : $content, $response->getStatusCode());
8899
});
89100
}
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
<?php
2+
3+
namespace Github\Tests\HttpClient\Plugin;
4+
5+
use Github\Exception\ExceptionInterface;
6+
use Github\HttpClient\Plugin\GithubExceptionThrower;
7+
use GuzzleHttp\Promise\FulfilledPromise;
8+
use GuzzleHttp\Psr7\Response;
9+
use PHPUnit\Framework\TestCase;
10+
use Psr\Http\Message\RequestInterface;
11+
use Psr\Http\Message\ResponseInterface;
12+
13+
/**
14+
* @author Sergii Ivashchenko <[email protected]>
15+
*/
16+
class GithubExceptionThrowerTest extends TestCase
17+
{
18+
/**
19+
* @param ResponseInterface $response
20+
* @param ExceptionInterface|\Exception|null $exception
21+
* @dataProvider responseProvider
22+
*/
23+
public function testHandleRequest(ResponseInterface $response, ExceptionInterface $exception = null)
24+
{
25+
/** @var RequestInterface $request */
26+
$request = $this->getMockForAbstractClass(RequestInterface::class);
27+
28+
$promise = $this->getMockBuilder(FulfilledPromise::class)->disableOriginalConstructor()->getMock();
29+
$promise->expects($this->once())
30+
->method('then')
31+
->willReturnCallback(function ($callback) use ($response) {
32+
return $callback($response);
33+
});
34+
35+
$plugin = new GithubExceptionThrower();
36+
37+
if ($exception) {
38+
$this->expectException(get_class($exception));
39+
$this->expectExceptionCode($exception->getCode());
40+
$this->expectExceptionMessage($exception->getMessage());
41+
}
42+
43+
$plugin->handleRequest(
44+
$request,
45+
function (RequestInterface $request) use ($promise) {
46+
return $promise;
47+
},
48+
function (RequestInterface $request) use ($promise) {
49+
return $promise;
50+
}
51+
);
52+
}
53+
54+
/**
55+
* @return array
56+
*/
57+
public static function responseProvider()
58+
{
59+
return [
60+
'200 Response' => [
61+
'response' => new Response(),
62+
'exception' => null,
63+
],
64+
'Rate Limit Exceeded' => [
65+
'response' => new Response(
66+
429,
67+
[
68+
'Content-Type' => 'application/json',
69+
'X-RateLimit-Remaining' => 0,
70+
'X-RateLimit-Limit' => 5000,
71+
],
72+
''
73+
),
74+
'exception' => new \Github\Exception\ApiLimitExceedException(5000),
75+
],
76+
'Two Factor Authentication Required' => [
77+
'response' => new Response(
78+
401,
79+
[
80+
'Content-Type' => 'application/json',
81+
'X-GitHub-OTP' => 'required; :2fa-type',
82+
],
83+
''
84+
),
85+
'exception' => new \Github\Exception\TwoFactorAuthenticationRequiredException('2fa-type'),
86+
],
87+
'400 Bad Request' => [
88+
'response' => new Response(
89+
400,
90+
[
91+
'Content-Type' => 'application/json',
92+
],
93+
json_encode(
94+
[
95+
'message' => 'Bad Request',
96+
]
97+
)
98+
),
99+
'exception' => new \Github\Exception\ErrorException('Bad Request', 400),
100+
],
101+
'422 Unprocessable Entity' => [
102+
'response' => new Response(
103+
422,
104+
[
105+
'Content-Type' => 'application/json',
106+
],
107+
json_encode(
108+
[
109+
'message' => 'Bad Request',
110+
'errors' => [
111+
[
112+
'code' => 'missing',
113+
'field' => 'field',
114+
'value' => 'value',
115+
'resource' => 'resource',
116+
],
117+
],
118+
]
119+
)
120+
),
121+
'exception' => new \Github\Exception\ErrorException('Validation Failed: The field value does not exist, for resource "resource"', 422),
122+
],
123+
'502 Response' => [
124+
'response' => new Response(
125+
502,
126+
[
127+
'Content-Type' => 'application/json',
128+
],
129+
json_encode(
130+
[
131+
'errors' => [
132+
['message' => 'Something went wrong with executing your query'],
133+
],
134+
]
135+
)
136+
),
137+
'exception' => new \Github\Exception\RuntimeException('Something went wrong with executing your query', 502),
138+
],
139+
'Default handling' => [
140+
'response' => new Response(
141+
555,
142+
[],
143+
'Error message'
144+
),
145+
'exception' => new \Github\Exception\RuntimeException('Error message', 555),
146+
],
147+
];
148+
}
149+
}

0 commit comments

Comments
 (0)