Browse Source

[HttpKernel] fixed Cache, to respect the variable and trigger error handling

Bulat Shakirzyanov 14 years ago
parent
commit
267a7e6956

+ 17 - 13
src/Symfony/Component/HttpKernel/Cache/Cache.php

@@ -145,11 +145,11 @@ class Cache implements HttpKernelInterface
         $this->traces[$request->getMethod().' '.$path] = array();
 
         if (!$request->isMethodSafe($request)) {
-            $response = $this->invalidate($request);
+            $response = $this->invalidate($request, $catch);
         } elseif ($request->headers->has('expect')) {
-            $response = $this->pass($request);
+            $response = $this->pass($request, $catch);
         } else {
-            $response = $this->lookup($request);
+            $response = $this->lookup($request, $catch);
         }
 
         $response->isNotModified($request);
@@ -171,33 +171,35 @@ class Cache implements HttpKernelInterface
      * Forwards the Request to the backend without storing the Response in the cache.
      *
      * @param Request $request A Request instance
+     * @param Boolean  $catch   whether to process exceptions
      *
      * @return Response A Response instance
      */
-    protected function pass(Request $request)
+    protected function pass(Request $request, $catch = false)
     {
         $this->record($request, 'pass');
 
-        return $this->forward($request);
+        return $this->forward($request, $catch);
     }
 
     /**
      * Invalidates non-safe methods (like POST, PUT, and DELETE).
      *
      * @param Request $request A Request instance
+     * @param Boolean  $catch   whether to process exceptions
      *
      * @return Response A Response instance
      *
      * @see RFC2616 13.10
      */
-    protected function invalidate(Request $request)
+    protected function invalidate(Request $request, $catch = false)
     {
-        $response = $this->pass($request);
+        $response = $this->pass($request, $catch);
 
         // invalidate only when the response is successful
         if ($response->isSuccessful() || $response->isRedirect()) {
             try {
-                $this->store->invalidate($request);
+                $this->store->invalidate($request, $catch);
 
                 $this->record($request, 'invalidate');
             } catch (\Exception $e) {
@@ -222,10 +224,11 @@ class Cache implements HttpKernelInterface
      * it triggers "miss" processing.
      *
      * @param Request $request A Request instance
+     * @param Boolean  $catch   whether to process exceptions
      *
      * @return Response A Response instance
      */
-    protected function lookup(Request $request)
+    protected function lookup(Request $request, $catch = false)
     {
         // if allow_reload and no-cache Cache-Control, allow a cache reload
         if ($this->options['allow_reload'] && $request->isNoCache()) {
@@ -243,13 +246,13 @@ class Cache implements HttpKernelInterface
                 throw $e;
             }
 
-            return $this->pass($request);
+            return $this->pass($request, $catch);
         }
 
         if (null === $entry) {
             $this->record($request, 'miss');
 
-            return $this->fetch($request);
+            return $this->fetch($request, $catch);
         }
 
         if (!$this->isFreshEnough($request, $entry)) {
@@ -332,10 +335,11 @@ class Cache implements HttpKernelInterface
      * This methods is trigered when the cache missed or a reload is required.
      *
      * @param Request  $request A Request instance
+     * @param Boolean  $catch   whether to process exceptions
      *
      * @return Response A Response instance
      */
-    protected function fetch(Request $request)
+    protected function fetch(Request $request, $catch = false)
     {
         $subRequest = clone $request;
 
@@ -346,7 +350,7 @@ class Cache implements HttpKernelInterface
         $subRequest->headers->remove('if_modified_since');
         $subRequest->headers->remove('if_none_match');
 
-        $response = $this->forward($subRequest);
+        $response = $this->forward($subRequest, $catch);
 
         if ($this->isPrivateRequest($request) && !$response->headers->hasCacheControlDirective('public')) {
             $response->setPrivate(true);

+ 20 - 0
tests/Symfony/Tests/Component/HttpKernel/Cache/CacheTest.php

@@ -870,4 +870,24 @@ class CacheTest extends CacheTestCase
         $this->assertEquals('Bob/2.0', $this->response->getContent());
         $this->assertEquals(3, $this->response->headers->get('X-Response-Count'));
     }
+
+    public function testShouldCatchExceptions()
+    {
+        $this->catchExceptions();
+
+        $this->setNextResponse();
+        $this->request('GET', '/');
+
+        $this->assertExceptionsAreCaught();
+    }
+
+    public function testShouldNotCatchExceptions()
+    {
+        $this->catchExceptions(false);
+
+        $this->setNextResponse();
+        $this->request('GET', '/');
+
+        $this->assertExceptionsAreNotCaught();
+    }
 }

+ 21 - 1
tests/Symfony/Tests/Component/HttpKernel/Cache/CacheTestCase.php

@@ -16,6 +16,7 @@ require_once __DIR__.'/TestHttpKernel.php';
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpKernel\Cache\Cache;
 use Symfony\Component\HttpKernel\Cache\Store;
+use Symfony\Component\HttpKernel\HttpKernelInterface;
 
 class CacheTestCase extends \PHPUnit_Framework_TestCase
 {
@@ -26,6 +27,7 @@ class CacheTestCase extends \PHPUnit_Framework_TestCase
     protected $request;
     protected $response;
     protected $responses;
+    protected $catch;
 
     protected function setUp()
     {
@@ -39,6 +41,8 @@ class CacheTestCase extends \PHPUnit_Framework_TestCase
         $this->response = null;
         $this->responses = array();
 
+        $this->catch = false;
+
         $this->clearDirectory(sys_get_temp_dir().'/http_cache');
     }
 
@@ -51,6 +55,7 @@ class CacheTestCase extends \PHPUnit_Framework_TestCase
         $this->response = null;
         $this->responses = null;
         $this->cacheConfig = null;
+        $this->catch = null;
 
         $this->clearDirectory(sys_get_temp_dir().'/http_cache');
     }
@@ -86,6 +91,16 @@ class CacheTestCase extends \PHPUnit_Framework_TestCase
         $this->assertNotRegExp('/'.$trace.'/', implode(', ', $traces));
     }
 
+    public function assertExceptionsAreCaught()
+    {
+        $this->assertTrue($this->kernel->isCatchingExceptions());
+    }
+
+    public function assertExceptionsAreNotCaught()
+    {
+        $this->assertFalse($this->kernel->isCatchingExceptions());
+    }
+
     public function request($method, $uri = '/', $server = array(), $cookies = array())
     {
         if (null === $this->kernel) {
@@ -100,7 +115,7 @@ class CacheTestCase extends \PHPUnit_Framework_TestCase
         $this->cache = new Cache($this->kernel, $this->store, null, $this->cacheConfig);
         $this->request = Request::create($uri, $method, array(), $cookies, array(), $server);
 
-        $this->response = $this->cache->handle($this->request);
+        $this->response = $this->cache->handle($this->request, HttpKernelInterface::MASTER_REQUEST, $this->catch);
 
         $this->responses[] = $this->response;
     }
@@ -123,6 +138,11 @@ class CacheTestCase extends \PHPUnit_Framework_TestCase
         $this->kernel = new TestHttpKernel($body, $statusCode, $headers, $customizer);
     }
 
+    public function catchExceptions($catch = true)
+    {
+        $this->catch = $catch;
+    }
+
     static public function clearDirectory($directory)
     {
         if (!is_dir($directory)) {

+ 14 - 0
tests/Symfony/Tests/Component/HttpKernel/Cache/TestHttpKernel.php

@@ -12,6 +12,7 @@
 namespace Symfony\Tests\Component\HttpKernel\Cache;
 
 use Symfony\Component\HttpKernel\HttpKernel;
+use Symfony\Component\HttpKernel\HttpKernelInterface;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpFoundation\Response;
 use Symfony\Component\EventDispatcher\EventDispatcher;
@@ -24,6 +25,7 @@ class TestHttpKernel extends HttpKernel implements ControllerResolverInterface
     protected $headers;
     protected $called;
     protected $customizer;
+    protected $catch;
 
     public function __construct($body, $status, $headers, \Closure $customizer = null)
     {
@@ -32,10 +34,22 @@ class TestHttpKernel extends HttpKernel implements ControllerResolverInterface
         $this->headers = $headers;
         $this->customizer = $customizer;
         $this->called = false;
+        $this->catch = false;
 
         parent::__construct(new EventDispatcher(), $this);
     }
 
+    public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = false)
+    {
+        $this->catch = $catch;
+        return parent::handle($request, $type, $catch);
+    }
+
+    public function isCatchingExceptions()
+    {
+        return $this->catch;
+    }
+
     public function getController(Request $request)
     {
         return array($this, 'callController');