Skip to content
This repository has been archived by the owner on Jan 29, 2020. It is now read-only.

Commit

Permalink
Merge pull request #46 from michaelmoussa/finalhandler-production-sta…
Browse files Browse the repository at this point in the history
…cktrace-fix

Finalhandler production stacktrace fix
  • Loading branch information
weierophinney committed Mar 17, 2016
2 parents bc78e7b + 675f7fc commit 43959d0
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 9 deletions.
28 changes: 19 additions & 9 deletions src/FinalHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,9 @@ class FinalHandler
*/
public function __construct(array $options = [], ResponseInterface $response = null)
{
$this->options = $options;
$this->response = $response;
$this->options = $options;

if ($response) {
$this->bodySize = $response->getBody()->getSize();
}
$this->setOriginalResponse($response);
}

/**
Expand Down Expand Up @@ -97,6 +94,20 @@ public function __invoke(RequestInterface $request, ResponseInterface $response,
return $this->create404($request, $response);
}

/**
* Set the original response and response body size for comparison.
*
* @param ResponseInterface $response
*/
public function setOriginalResponse(ResponseInterface $response = null)
{
$this->response = $response;

if ($response) {
$this->bodySize = $response->getBody()->getSize();
}
}

/**
* Handle an error condition
*
Expand All @@ -110,13 +121,12 @@ public function __invoke(RequestInterface $request, ResponseInterface $response,
private function handleError($error, RequestInterface $request, ResponseInterface $response)
{
$response = $response->withStatus(
Utils::getStatusCode($error, $response)
Utils::getStatusCode($error, $response),
$response->getReasonPhrase()
);

$message = $response->getReasonPhrase() ?: 'Unknown Error';
if (! isset($this->options['env'])
|| $this->options['env'] !== 'production'
) {
if (isset($this->options['env']) && $this->options['env'] !== 'production') {
$message = $this->createDevelopmentErrorMessage($error);
}

Expand Down
48 changes: 48 additions & 0 deletions test/FinalHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,15 @@ public function testInvokingWithExceptionWithInvalidCodeSetsStatusTo500()
public function testInvokingWithErrorInNonProductionModeSetsResponseBodyToError()
{
$error = 'error';
$this->final = new FinalHandler(['env' => 'not-production']);
$response = call_user_func($this->final, $this->request, $this->response, $error);
$this->assertEquals($error, (string) $response->getBody());
}

public function testInvokingWithExceptionInNonProductionModeIncludesExceptionMessageInResponseBody()
{
$error = new Exception('foo', 400);
$this->final = new FinalHandler(['env' => 'not-production']);
$response = call_user_func($this->final, $this->request, $this->response, $error);
$expected = $this->escaper->escapeHtml($error->getMessage());
$this->assertContains($expected, (string) $response->getBody());
Expand All @@ -69,6 +71,7 @@ public function testInvokingWithExceptionInNonProductionModeIncludesExceptionMes
public function testInvokingWithExceptionInNonProductionModeIncludesTraceInResponseBody()
{
$error = new Exception('foo', 400);
$this->final = new FinalHandler(['env' => 'not-production']);
$response = call_user_func($this->final, $this->request, $this->response, $error);
$expected = $this->escaper->escapeHtml($error->getTraceAsString());
$this->assertContains($expected, (string) $response->getBody());
Expand All @@ -86,6 +89,29 @@ public function testInvokingWithExceptionInNonProductionModeIncludesPrevTraceInR
$this->assertContains('foo', $body);
}

public function testInvokingWithErrorAndNoEnvironmentModeSetDoesNotSetResponseBodyToError()
{
$error = 'error';
$response = call_user_func($this->final, $this->request, $this->response, $error);
$this->assertNotEquals($error, (string) $response->getBody());
}

public function testInvokingWithExceptionAndNoEnvironmentModeSetDoesNotIncludeExceptionMessageInResponseBody()
{
$error = new Exception('foo', 400);
$response = call_user_func($this->final, $this->request, $this->response, $error);
$expected = $this->escaper->escapeHtml($error->getMessage());
$this->assertNotContains($expected, (string) $response->getBody());
}

public function testInvokingWithExceptionAndNoEnvironmentModeSetDoesNotIncludeTraceInResponseBody()
{
$error = new Exception('foo', 400);
$response = call_user_func($this->final, $this->request, $this->response, $error);
$expected = $this->escaper->escapeHtml($error->getTraceAsString());
$this->assertNotContains($expected, (string) $response->getBody());
}

public function testInvokingWithErrorInProductionSetsResponseToReasonPhrase()
{
$final = new FinalHandler([
Expand Down Expand Up @@ -122,6 +148,13 @@ public function testCreates404ResponseWhenNoErrorIsPresent()
$this->assertEquals(404, $response->getStatusCode());
}

public function testErrorResponsePreservesOriginalReasonPhraseIfSet()
{
$this->response = $this->response->withStatus(500, 'It broke!');
$response = call_user_func($this->final, $this->request, $this->response, new \Exception('foo'));
$this->assertSame($this->response->getReasonPhrase(), $response->getReasonPhrase());
}

public function test404ResponseIncludesOriginalRequestUri()
{
$originalUrl = 'http://local.example.com/bar/foo';
Expand Down Expand Up @@ -162,4 +195,19 @@ public function testReturnsResponseIfBodyLengthHasChanged()
$result = $final(new Request(new PsrRequest()), $response);
$this->assertSame($response, $result);
}

public function testCanReplaceOriginalResponseAndBodySizeAfterConstruction()
{
$psrResponse = new PsrResponse();
$originalResponse = new Response(new PsrResponse());
$originalResponse->write('foo');

$final = new FinalHandler([], $psrResponse);
$final->setOriginalResponse($originalResponse);

/** @var Response $actualResponse */
$actualResponse = self::readAttribute($final, 'response');
$this->assertSame($originalResponse, $actualResponse);
$this->assertSame(3, $actualResponse->getBody()->getSize());
}
}

0 comments on commit 43959d0

Please sign in to comment.