From 9c69bfcee849bc9b65334dde0e2066adad89b8c5 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Tue, 9 Feb 2016 21:40:11 +0100 Subject: [PATCH 1/9] Improve error reporting in router panel of web profiler --- .../Resources/views/Router/panel.html.twig | 21 +++++++++++++------ .../Routing/Matcher/TraceableUrlMatcher.php | 8 ++++++- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Router/panel.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Router/panel.html.twig index db7610ea197bd..2f7fd76284b8b 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Router/panel.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Router/panel.html.twig @@ -31,14 +31,23 @@ Log {% for trace in traces %} - - {{ trace.name }} - {{ trace.path }} - {{ trace.log }} - + {% if trace.level == -1 %} + + + {{ trace.name }} + + + {% else %} + + {{ trace.name }} + {{ trace.path }} + {{ trace.log }} + + {% endif %} {% endfor %} Note: The above matching is based on the configuration for the current router which might differ from - the configuration used while routing this request. + the configuration used while routing this request. + Logs are not available for routes that define conditions using the "request" object. diff --git a/src/Symfony/Component/Routing/Matcher/TraceableUrlMatcher.php b/src/Symfony/Component/Routing/Matcher/TraceableUrlMatcher.php index ef4f24c6c65f2..7fe6ad9433f28 100644 --- a/src/Symfony/Component/Routing/Matcher/TraceableUrlMatcher.php +++ b/src/Symfony/Component/Routing/Matcher/TraceableUrlMatcher.php @@ -34,7 +34,13 @@ public function getTraces($pathinfo) try { $this->match($pathinfo); - } catch (ExceptionInterface $e) { + } catch (\Exception $e) { + $this->traces = array(array( + 'name' => sprintf('[ERROR] The following exception prevented the route to be matched against application routes: "%s" (in %s line %d)', $e->getMessage(), $e->getFile(), $e->getLine()), + 'log' => '-', + 'level' => -1, + 'path' => '-' + )); } return $this->traces; From 07ba6c3e4250db3e47841e8894e42e23717aafdf Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Tue, 9 Feb 2016 21:53:08 +0100 Subject: [PATCH 2/9] Fixed fabbot issues --- src/Symfony/Component/Routing/Matcher/TraceableUrlMatcher.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Symfony/Component/Routing/Matcher/TraceableUrlMatcher.php b/src/Symfony/Component/Routing/Matcher/TraceableUrlMatcher.php index 7fe6ad9433f28..514991059f298 100644 --- a/src/Symfony/Component/Routing/Matcher/TraceableUrlMatcher.php +++ b/src/Symfony/Component/Routing/Matcher/TraceableUrlMatcher.php @@ -11,7 +11,6 @@ namespace Symfony\Component\Routing\Matcher; -use Symfony\Component\Routing\Exception\ExceptionInterface; use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouteCollection; @@ -39,7 +38,7 @@ public function getTraces($pathinfo) 'name' => sprintf('[ERROR] The following exception prevented the route to be matched against application routes: "%s" (in %s line %d)', $e->getMessage(), $e->getFile(), $e->getLine()), 'log' => '-', 'level' => -1, - 'path' => '-' + 'path' => '-', )); } From 098d3000cc0283d80e4a38b91bbfa4a85b64e612 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Wed, 10 Feb 2016 08:41:05 +0100 Subject: [PATCH 3/9] Fixed tests and added a new test --- .../Resources/views/Router/panel.html.twig | 2 +- .../Routing/Matcher/TraceableUrlMatcher.php | 6 ++++-- .../Tests/Matcher/TraceableUrlMatcherTest.php | 15 +++++++++++++++ 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Router/panel.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Router/panel.html.twig index 2f7fd76284b8b..8da87e8f675d9 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Router/panel.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Router/panel.html.twig @@ -34,7 +34,7 @@ {% if trace.level == -1 %} - {{ trace.name }} + {{ trace.log }} {% else %} diff --git a/src/Symfony/Component/Routing/Matcher/TraceableUrlMatcher.php b/src/Symfony/Component/Routing/Matcher/TraceableUrlMatcher.php index 514991059f298..8120ecff38629 100644 --- a/src/Symfony/Component/Routing/Matcher/TraceableUrlMatcher.php +++ b/src/Symfony/Component/Routing/Matcher/TraceableUrlMatcher.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Routing\Matcher; +use Symfony\Component\Routing\Exception\ExceptionInterface; use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouteCollection; @@ -33,11 +34,12 @@ public function getTraces($pathinfo) try { $this->match($pathinfo); + } catch (ExceptionInterface $e) { } catch (\Exception $e) { $this->traces = array(array( - 'name' => sprintf('[ERROR] The following exception prevented the route to be matched against application routes: "%s" (in %s line %d)', $e->getMessage(), $e->getFile(), $e->getLine()), - 'log' => '-', 'level' => -1, + 'log' => sprintf('[ERROR] The following exception prevented the route to be matched against application routes: "%s" (in %s line %d)', $e->getMessage(), $e->getFile(), $e->getLine()), + 'name' => '-', 'path' => '-', )); } diff --git a/src/Symfony/Component/Routing/Tests/Matcher/TraceableUrlMatcherTest.php b/src/Symfony/Component/Routing/Tests/Matcher/TraceableUrlMatcherTest.php index 20b30d7b91264..9a034ef7bf0c4 100644 --- a/src/Symfony/Component/Routing/Tests/Matcher/TraceableUrlMatcherTest.php +++ b/src/Symfony/Component/Routing/Tests/Matcher/TraceableUrlMatcherTest.php @@ -98,4 +98,19 @@ public function getLevels($traces) return $levels; } + + public function testExceptionOnRouteCondition() + { + $coll = new RouteCollection(); + $coll->add('foo', new Route('/foo', array(), array(), array(), 'baz', array(), array(), "request.headers.get('User-Agent') matches '/firefox/i'")); + + $context = new RequestContext(); + $context->setHost('baz'); + + $matcher = new TraceableUrlMatcher($coll, $context); + $traces = $matcher->getTraces('/foo'); + + $this->assertEquals(-1, $traces[0]['level']); + $this->assertRegExp('/\[ERROR\] The following exception prevented the route to be matched against application routes: "Unable to get a property on a non-object\." \(in .* line \d+\)/', $traces[0]['log']); + } } From d4887f97575dd56ef30ac87fb9af461e4becfb18 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Mon, 29 Feb 2016 08:51:06 +0100 Subject: [PATCH 4/9] Refactored the solution --- .../Controller/RouterController.php | 34 ++++++++++++++++--- .../Resources/views/Router/panel.html.twig | 21 ++++-------- .../Routing/Matcher/TraceableUrlMatcher.php | 17 ++++++---- 3 files changed, 45 insertions(+), 27 deletions(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Controller/RouterController.php b/src/Symfony/Bundle/WebProfilerBundle/Controller/RouterController.php index f4a84bf568730..e1f6beb4b668b 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Controller/RouterController.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Controller/RouterController.php @@ -18,6 +18,7 @@ use Symfony\Component\Routing\RouterInterface; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\Profiler\Profiler; +use Symfony\Component\HttpKernel\DataCollector\RequestDataCollector; /** * RouterController. @@ -62,16 +63,39 @@ public function panelAction($token) $profile = $this->profiler->loadProfile($token); - $context = $this->matcher->getContext(); - $context->setMethod($profile->getMethod()); - $matcher = new TraceableUrlMatcher($this->routes, $context); - + /** @var RequestDataCollector $request */ $request = $profile->getCollector('request'); return new Response($this->twig->render('@WebProfiler/Router/panel.html.twig', array( 'request' => $request, 'router' => $profile->getCollector('router'), - 'traces' => $matcher->getTraces($request->getPathInfo()), + 'traces' => $this->getTraces($request, $profile->getMethod()), )), 200, array('Content-Type' => 'text/html')); } + + /** + * Returns the routing traces associated to the given request. + * + * @param RequestDataCollector $request + * @param string $method + * + * @return array + */ + private function getTraces(RequestDataCollector $request, $method) + { + $traceRequest = Request::create( + $request->getPathInfo(), + $request->getRequestServer()->get('REQUEST_METHOD'), + $request->getRequestAttributes()->all(), + $request->getRequestCookies()->all(), + [], + $request->getRequestServer()->all() + ); + + $context = $this->matcher->getContext(); + $context->setMethod($method); + $matcher = new TraceableUrlMatcher($this->routes, $context); + + return $matcher->getTracesFromRequest($traceRequest); + } } diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Router/panel.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Router/panel.html.twig index 8da87e8f675d9..db7610ea197bd 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Router/panel.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Router/panel.html.twig @@ -31,23 +31,14 @@ Log {% for trace in traces %} - {% if trace.level == -1 %} - - - {{ trace.log }} - - - {% else %} - - {{ trace.name }} - {{ trace.path }} - {{ trace.log }} - - {% endif %} + + {{ trace.name }} + {{ trace.path }} + {{ trace.log }} + {% endfor %} Note: The above matching is based on the configuration for the current router which might differ from - the configuration used while routing this request. - Logs are not available for routes that define conditions using the "request" object. + the configuration used while routing this request. diff --git a/src/Symfony/Component/Routing/Matcher/TraceableUrlMatcher.php b/src/Symfony/Component/Routing/Matcher/TraceableUrlMatcher.php index 8120ecff38629..ce4aea3ad6b4f 100644 --- a/src/Symfony/Component/Routing/Matcher/TraceableUrlMatcher.php +++ b/src/Symfony/Component/Routing/Matcher/TraceableUrlMatcher.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Routing\Matcher; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Exception\ExceptionInterface; use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouteCollection; @@ -35,18 +36,20 @@ public function getTraces($pathinfo) try { $this->match($pathinfo); } catch (ExceptionInterface $e) { - } catch (\Exception $e) { - $this->traces = array(array( - 'level' => -1, - 'log' => sprintf('[ERROR] The following exception prevented the route to be matched against application routes: "%s" (in %s line %d)', $e->getMessage(), $e->getFile(), $e->getLine()), - 'name' => '-', - 'path' => '-', - )); } return $this->traces; } + public function getTracesFromRequest(Request $request) + { + $this->request = $request; + $traces = $this->getTraces($request->getPathInfo()); + $this->request = null; + + return $traces; + } + protected function matchCollection($pathinfo, RouteCollection $routes) { foreach ($routes as $name => $route) { From 772186490ded48e817b0c8101be335bc9afa12ed Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Mon, 29 Feb 2016 08:51:57 +0100 Subject: [PATCH 5/9] Fixed fabbot issues --- .../Bundle/WebProfilerBundle/Controller/RouterController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Controller/RouterController.php b/src/Symfony/Bundle/WebProfilerBundle/Controller/RouterController.php index e1f6beb4b668b..952e11612954a 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Controller/RouterController.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Controller/RouterController.php @@ -76,8 +76,8 @@ public function panelAction($token) /** * Returns the routing traces associated to the given request. * - * @param RequestDataCollector $request - * @param string $method + * @param RequestDataCollector $request + * @param string $method * * @return array */ From 0969aee3117bcfc146b888df9d2b9e55d487f870 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Mon, 29 Feb 2016 10:33:52 +0100 Subject: [PATCH 6/9] Updated tests --- .../Controller/RouterController.php | 2 +- .../Tests/Matcher/TraceableUrlMatcherTest.php | 19 ++++++++++++------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Controller/RouterController.php b/src/Symfony/Bundle/WebProfilerBundle/Controller/RouterController.php index 952e11612954a..9e989b36bc8ed 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Controller/RouterController.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Controller/RouterController.php @@ -88,7 +88,7 @@ private function getTraces(RequestDataCollector $request, $method) $request->getRequestServer()->get('REQUEST_METHOD'), $request->getRequestAttributes()->all(), $request->getRequestCookies()->all(), - [], + array(), $request->getRequestServer()->all() ); diff --git a/src/Symfony/Component/Routing/Tests/Matcher/TraceableUrlMatcherTest.php b/src/Symfony/Component/Routing/Tests/Matcher/TraceableUrlMatcherTest.php index 9a034ef7bf0c4..6d6657080f4d5 100644 --- a/src/Symfony/Component/Routing/Tests/Matcher/TraceableUrlMatcherTest.php +++ b/src/Symfony/Component/Routing/Tests/Matcher/TraceableUrlMatcherTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Routing\Tests\Matcher; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Routing\RequestContext; @@ -99,18 +100,22 @@ public function getLevels($traces) return $levels; } - public function testExceptionOnRouteCondition() + public function testRoutesWithConditions() { - $coll = new RouteCollection(); - $coll->add('foo', new Route('/foo', array(), array(), array(), 'baz', array(), array(), "request.headers.get('User-Agent') matches '/firefox/i'")); + $routes = new RouteCollection(); + $routes->add('foo', new Route('/foo', array(), array(), array(), 'baz', array(), array(), "request.headers.get('User-Agent') matches '/firefox/i'")); $context = new RequestContext(); $context->setHost('baz'); - $matcher = new TraceableUrlMatcher($coll, $context); - $traces = $matcher->getTraces('/foo'); + $matcher = new TraceableUrlMatcher($routes, $context); + + $notMatchingRequest = Request::create('/foo', 'GET'); + $traces = $matcher->getTracesFromRequest($notMatchingRequest); + $this->assertEquals("Condition \"request.headers.get('User-Agent') matches '/firefox/i'\" does not evaluate to \"true\"", $traces[0]['log']); - $this->assertEquals(-1, $traces[0]['level']); - $this->assertRegExp('/\[ERROR\] The following exception prevented the route to be matched against application routes: "Unable to get a property on a non-object\." \(in .* line \d+\)/', $traces[0]['log']); + $matchingRequest = Request::create('/foo', 'GET', array(), array(), array(), array('HTTP_USER_AGENT' => 'Firefox')); + $traces = $matcher->getTracesFromRequest($matchingRequest); + $this->assertEquals("Route matches!", $traces[0]['log']); } } From 0c964507663a2b66856032f025bc1d0fe1426ad2 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Mon, 29 Feb 2016 14:44:17 +0100 Subject: [PATCH 7/9] Fixed a fabbot issue --- .../Component/Routing/Tests/Matcher/TraceableUrlMatcherTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Routing/Tests/Matcher/TraceableUrlMatcherTest.php b/src/Symfony/Component/Routing/Tests/Matcher/TraceableUrlMatcherTest.php index 6d6657080f4d5..5510ab87b79dc 100644 --- a/src/Symfony/Component/Routing/Tests/Matcher/TraceableUrlMatcherTest.php +++ b/src/Symfony/Component/Routing/Tests/Matcher/TraceableUrlMatcherTest.php @@ -116,6 +116,6 @@ public function testRoutesWithConditions() $matchingRequest = Request::create('/foo', 'GET', array(), array(), array(), array('HTTP_USER_AGENT' => 'Firefox')); $traces = $matcher->getTracesFromRequest($matchingRequest); - $this->assertEquals("Route matches!", $traces[0]['log']); + $this->assertEquals('Route matches!', $traces[0]['log']); } } From 29db6e04780578b9c93ea85d073bd22b1bc648ba Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Tue, 1 Mar 2016 15:25:50 +0100 Subject: [PATCH 8/9] getTracesFromRequest -> getTracesForRequest --- .../Bundle/WebProfilerBundle/Controller/RouterController.php | 2 +- src/Symfony/Component/Routing/Matcher/TraceableUrlMatcher.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Controller/RouterController.php b/src/Symfony/Bundle/WebProfilerBundle/Controller/RouterController.php index 9e989b36bc8ed..2be420ba8b0b0 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Controller/RouterController.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Controller/RouterController.php @@ -96,6 +96,6 @@ private function getTraces(RequestDataCollector $request, $method) $context->setMethod($method); $matcher = new TraceableUrlMatcher($this->routes, $context); - return $matcher->getTracesFromRequest($traceRequest); + return $matcher->getTracesForRequest($traceRequest); } } diff --git a/src/Symfony/Component/Routing/Matcher/TraceableUrlMatcher.php b/src/Symfony/Component/Routing/Matcher/TraceableUrlMatcher.php index ce4aea3ad6b4f..cb1a35f4d3023 100644 --- a/src/Symfony/Component/Routing/Matcher/TraceableUrlMatcher.php +++ b/src/Symfony/Component/Routing/Matcher/TraceableUrlMatcher.php @@ -41,7 +41,7 @@ public function getTraces($pathinfo) return $this->traces; } - public function getTracesFromRequest(Request $request) + public function getTracesForRequest(Request $request) { $this->request = $request; $traces = $this->getTraces($request->getPathInfo()); From e5bb235da6de48d54bb282703683350d42d6efd1 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Thu, 3 Mar 2016 11:19:25 +0100 Subject: [PATCH 9/9] Fixed tests --- .../Routing/Tests/Matcher/TraceableUrlMatcherTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Routing/Tests/Matcher/TraceableUrlMatcherTest.php b/src/Symfony/Component/Routing/Tests/Matcher/TraceableUrlMatcherTest.php index 5510ab87b79dc..e43cbcb6bd148 100644 --- a/src/Symfony/Component/Routing/Tests/Matcher/TraceableUrlMatcherTest.php +++ b/src/Symfony/Component/Routing/Tests/Matcher/TraceableUrlMatcherTest.php @@ -111,11 +111,11 @@ public function testRoutesWithConditions() $matcher = new TraceableUrlMatcher($routes, $context); $notMatchingRequest = Request::create('/foo', 'GET'); - $traces = $matcher->getTracesFromRequest($notMatchingRequest); + $traces = $matcher->getTracesForRequest($notMatchingRequest); $this->assertEquals("Condition \"request.headers.get('User-Agent') matches '/firefox/i'\" does not evaluate to \"true\"", $traces[0]['log']); $matchingRequest = Request::create('/foo', 'GET', array(), array(), array(), array('HTTP_USER_AGENT' => 'Firefox')); - $traces = $matcher->getTracesFromRequest($matchingRequest); + $traces = $matcher->getTracesForRequest($matchingRequest); $this->assertEquals('Route matches!', $traces[0]['log']); } }