Skip to content

Commit

Permalink
bug #23052 [TwigBundle] Add Content-Type header for exception respons…
Browse files Browse the repository at this point in the history
…e (rchoquet)

This PR was merged into the 2.7 branch.

Discussion
----------

[TwigBundle] Add Content-Type header for exception response

| Q             | A
| ------------- | ---
| Branch?       | 2.7
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets |
| License       | MIT
| Doc PR        |

This PR comes after I was looking to customize the way exceptions are served for a JSON API (grabbed the info at http://symfony.com/doc/current/controller/error_pages.html#overriding-the-default-exceptioncontroller).

I noticed that even when changing the request format to 'json' so that the right json.twig template is served:
```php
// in my override of the ExceptionController
public function showAction(Request $request, FlattenException $exception, DebugLoggerInterface $logger = null)
{
    $request->setRequestFormat('json');
    return parent::showAction($request, $exception, $logger);
}
```
the response Content-Type header was still 'text/html'.

By now, the response Content-Type should be corresponding to the given request format.

I also feel there's some room for improvement with the general "displaying error for a JSON API" chapter as it feels strange that there's no configuration option to just say "serve me anything as json", but that's another issue.

Commits
-------

9e2b408 add content-type header on exception response
  • Loading branch information
fabpot committed Jun 16, 2017
2 parents b8c94d0 + 9e2b408 commit c8884e7
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 18 deletions.
Expand Up @@ -74,7 +74,7 @@ public function showAction(Request $request, FlattenException $exception, DebugL
'logger' => $logger,
'currentContent' => $currentContent,
)
));
), 200, array('Content-Type' => $request->getMimeType($request->getRequestFormat()) ?: 'text/html'));
}

/**
Expand Down
Expand Up @@ -22,40 +22,57 @@ class ExceptionControllerTest extends TestCase
{
public function testShowActionCanBeForcedToShowErrorPage()
{
$twig = new Environment(
new ArrayLoader(array(
'TwigBundle:Exception:error404.html.twig' => 'ok',
))
);
$twig = $this->createTwigEnv(array('TwigBundle:Exception:error404.html.twig' => '<html>not found</html>'));

$request = Request::create('whatever', 'GET');
$request->headers->set('X-Php-Ob-Level', 1);
$request = $this->createRequest('html');
$request->attributes->set('showException', false);
$exception = FlattenException::create(new \Exception(), 404);
$controller = new ExceptionController($twig, /* "showException" defaults to --> */ true);

$response = $controller->showAction($request, $exception, null);

$this->assertEquals(200, $response->getStatusCode()); // successful request
$this->assertEquals('ok', $response->getContent()); // content of the error404.html template
$this->assertEquals('<html>not found</html>', $response->getContent());
}

public function testFallbackToHtmlIfNoTemplateForRequestedFormat()
{
$twig = new Environment(
new ArrayLoader(array(
'TwigBundle:Exception:error.html.twig' => 'html',
))
);
$twig = $this->createTwigEnv(array('TwigBundle:Exception:error.html.twig' => '<html></html>'));

$request = Request::create('whatever');
$request->headers->set('X-Php-Ob-Level', 1);
$request->setRequestFormat('txt');
$request = $this->createRequest('txt');
$exception = FlattenException::create(new \Exception());
$controller = new ExceptionController($twig, false);

$response = $controller->showAction($request, $exception);
$controller->showAction($request, $exception);

$this->assertEquals('html', $request->getRequestFormat());
}

public function testResponseHasRequestedMimeType()
{
$twig = $this->createTwigEnv(array('TwigBundle:Exception:error.json.twig' => '{}'));

$request = $this->createRequest('json');
$exception = FlattenException::create(new \Exception());
$controller = new ExceptionController($twig, false);

$response = $controller->showAction($request, $exception);

$this->assertEquals('json', $request->getRequestFormat());
$this->assertEquals($request->getMimeType('json'), $response->headers->get('Content-Type'));
}

private function createRequest($requestFormat)
{
$request = Request::create('whatever');
$request->headers->set('X-Php-Ob-Level', 1);
$request->setRequestFormat($requestFormat);

return $request;
}

private function createTwigEnv(array $templates)
{
return new Environment(new ArrayLoader($templates));
}
}

0 comments on commit c8884e7

Please sign in to comment.