1
0
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:
Michael Dowling 2015-10-26 20:47:11 -07:00
commit 1654679ba0
4 changed files with 113 additions and 20 deletions

View File

@ -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
*

View File

@ -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);
}
);
};

View File

@ -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);

View File

@ -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);
}
}