mirror of
https://github.com/guzzle/guzzle.git
synced 2025-02-24 01:53:58 +01:00
Merge remote-tracking branch 'shadowhand/hotfix/improved-middleware-exception' into response-body-exception
This commit is contained in:
commit
1654679ba0
@ -79,24 +79,63 @@ class RequestException extends TransferException
|
||||
|
||||
$level = floor($response->getStatusCode() / 100);
|
||||
if ($level == '4') {
|
||||
$label = 'Client error response';
|
||||
$label = 'Client Error';
|
||||
$className = __NAMESPACE__ . '\\ClientException';
|
||||
} elseif ($level == '5') {
|
||||
$label = 'Server error response';
|
||||
$label = 'Server Error';
|
||||
$className = __NAMESPACE__ . '\\ServerException';
|
||||
} else {
|
||||
$label = 'Unsuccessful response';
|
||||
$label = 'Unsuccessful Request';
|
||||
$className = __CLASS__;
|
||||
}
|
||||
|
||||
$message = $label . ' [url] ' . $request->getUri()
|
||||
. ' [http method] ' . $request->getMethod()
|
||||
. ' [status code] ' . $response->getStatusCode()
|
||||
. ' [reason phrase] ' . $response->getReasonPhrase();
|
||||
// Server Error: `GET /` resulted in a `404 Not Found` response:
|
||||
// <html> ... (truncated)
|
||||
$message = sprintf(
|
||||
'%s: `%s` resulted in a `%s` response',
|
||||
$label,
|
||||
$request->getMethod() . ' ' . $request->getUri(),
|
||||
$response->getStatusCode() . ' ' . $response->getReasonPhrase()
|
||||
);
|
||||
|
||||
$summary = static::getResponseBodySummary($response);
|
||||
|
||||
if (is_string($summary)) {
|
||||
$message .= ":\n{$summary}\n";
|
||||
}
|
||||
|
||||
return new $className($message, $request, $response, $previous, $ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a short summary of the response
|
||||
*
|
||||
* Will return `null` if the response is not printable.
|
||||
*
|
||||
* @param ResponseInterface $response
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public static function getResponseBodySummary(ResponseInterface $response)
|
||||
{
|
||||
$body = $response->getBody();
|
||||
|
||||
if (!$body->isSeekable()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$summary = $body->read(120);
|
||||
$body->rewind();
|
||||
|
||||
// Matches any printable character, including unicode characters:
|
||||
// letters, marks, numbers, punctuation, spacing, and separators.
|
||||
if (preg_match('/[^\pL\pM\pN\pP\pS\pZ\n\r\t]/', $summary)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $summary;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the request that caused the exception
|
||||
*
|
||||
|
@ -2,9 +2,7 @@
|
||||
namespace GuzzleHttp;
|
||||
|
||||
use GuzzleHttp\Cookie\CookieJarInterface;
|
||||
use GuzzleHttp\Exception\ClientException;
|
||||
use GuzzleHttp\Exception\RequestException;
|
||||
use GuzzleHttp\Exception\ServerException;
|
||||
use GuzzleHttp\Promise\RejectedPromise;
|
||||
use GuzzleHttp\Psr7;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
@ -64,9 +62,7 @@ final class Middleware
|
||||
if ($code < 400) {
|
||||
return $response;
|
||||
}
|
||||
throw $code > 499
|
||||
? new ServerException("Server error: $code", $request, $response)
|
||||
: new ClientException("Client error: $code", $request, $response);
|
||||
throw RequestException::create($request, $response);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
@ -31,8 +31,12 @@ class RequestExceptionTest extends \PHPUnit_Framework_TestCase
|
||||
public function testCreatesClientErrorResponseException()
|
||||
{
|
||||
$e = RequestException::create(new Request('GET', '/'), new Response(400));
|
||||
$this->assertEquals(
|
||||
'Client error response [url] / [http method] GET [status code] 400 [reason phrase] Bad Request',
|
||||
$this->assertContains(
|
||||
'GET /',
|
||||
$e->getMessage()
|
||||
);
|
||||
$this->assertContains(
|
||||
'400 Bad Request',
|
||||
$e->getMessage()
|
||||
);
|
||||
$this->assertInstanceOf('GuzzleHttp\Exception\ClientException', $e);
|
||||
@ -41,8 +45,12 @@ class RequestExceptionTest extends \PHPUnit_Framework_TestCase
|
||||
public function testCreatesServerErrorResponseException()
|
||||
{
|
||||
$e = RequestException::create(new Request('GET', '/'), new Response(500));
|
||||
$this->assertEquals(
|
||||
'Server error response [url] / [http method] GET [status code] 500 [reason phrase] Internal Server Error',
|
||||
$this->assertContains(
|
||||
'GET /',
|
||||
$e->getMessage()
|
||||
);
|
||||
$this->assertContains(
|
||||
'500 Internal Server Error',
|
||||
$e->getMessage()
|
||||
);
|
||||
$this->assertInstanceOf('GuzzleHttp\Exception\ServerException', $e);
|
||||
@ -51,8 +59,57 @@ class RequestExceptionTest extends \PHPUnit_Framework_TestCase
|
||||
public function testCreatesGenericErrorResponseException()
|
||||
{
|
||||
$e = RequestException::create(new Request('GET', '/'), new Response(600));
|
||||
$this->assertEquals(
|
||||
'Unsuccessful response [url] / [http method] GET [status code] 600 [reason phrase] ',
|
||||
$this->assertContains(
|
||||
'GET /',
|
||||
$e->getMessage()
|
||||
);
|
||||
$this->assertContains(
|
||||
'600 ',
|
||||
$e->getMessage()
|
||||
);
|
||||
$this->assertInstanceOf('GuzzleHttp\Exception\RequestException', $e);
|
||||
}
|
||||
|
||||
public function dataPrintableResponses()
|
||||
{
|
||||
return [
|
||||
['You broke the test!'],
|
||||
['<h1>zlomený zkouška</h1>'],
|
||||
['{"tester": "Philépe Gonzalez"}'],
|
||||
["<xml>\n\t<text>Your friendly test</text>\n</xml>"],
|
||||
['document.body.write("here comes a test");'],
|
||||
["body:before {\n\tcontent: 'test style';\n}"],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataPrintableResponses
|
||||
*/
|
||||
public function testCreatesExceptionWithPrintableBodySummary($content)
|
||||
{
|
||||
$response = new Response(
|
||||
500,
|
||||
[],
|
||||
$content
|
||||
);
|
||||
$e = RequestException::create(new Request('GET', '/'), $response);
|
||||
$this->assertContains(
|
||||
$content,
|
||||
$e->getMessage()
|
||||
);
|
||||
$this->assertInstanceOf('GuzzleHttp\Exception\RequestException', $e);
|
||||
}
|
||||
|
||||
public function testCreatesExceptionWithoutPrintableBody()
|
||||
{
|
||||
$response = new Response(
|
||||
500,
|
||||
['Content-Type' => 'image/gif'],
|
||||
$content = base64_decode('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7') // 1x1 gif
|
||||
);
|
||||
$e = RequestException::create(new Request('GET', '/'), $response);
|
||||
$this->assertNotContains(
|
||||
$content,
|
||||
$e->getMessage()
|
||||
);
|
||||
$this->assertInstanceOf('GuzzleHttp\Exception\RequestException', $e);
|
||||
|
@ -193,13 +193,14 @@ class MiddlewareTest extends \PHPUnit_Framework_TestCase
|
||||
$h = new MockHandler([new Response(404)]);
|
||||
$stack = new HandlerStack($h);
|
||||
$logger = new Logger();
|
||||
$formatter = new MessageFormatter('"{method} {target} HTTP/{version}\" {code} {error}');
|
||||
$formatter = new MessageFormatter('{code} {error}');
|
||||
$stack->push(Middleware::log($logger, $formatter));
|
||||
$stack->push(Middleware::httpErrors());
|
||||
$comp = $stack->resolve();
|
||||
$p = $comp(new Request('PUT', 'http://www.google.com'), ['http_errors' => true]);
|
||||
$p->wait(false);
|
||||
$this->assertContains('"PUT / HTTP/1.1\" 404 Client error: 404', $logger->output);
|
||||
$this->assertContains('PUT http://www.google.com', $logger->output);
|
||||
$this->assertContains('404 Not Found', $logger->output);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user