Symfony php Custom exception controller not working - php

I'm trying to create a custom exception controller in php Symfony 4. Essentially what I want to do is to have a default route that gets called when no other routes match.
I'm trying to follow the suggestions here:
https://symfony.com/doc/current/controller/error_pages.html#custom-exception-controller
I've created the twig.yaml file inside configs>>pacakges:
twig:
exception_controller: App\Controller\ExceptionController::showException
I've also created the ExceptionController class:
<?php
namespace App\Controller;
use Symfony\Component\HttpFoundation\Response;
class ExceptionController
{
public function showException()
{
$response = new Response();
$response->setContent("Some random text");
$response->headers->set('Content-Type', 'text/plain');
$response->headers->set('Access-Control-Allow-Origin', '*');
$response->setStatusCode(200);
return $response;
}
}
When I visit a url that does not exist I'm expecting to see the text "Some random text" but instead I get the default symfony not found page:
Any ideas what I might be doing wrong?

You mentioned that you created a twig.yaml under configs/packages.
Two things:
This should be config, not configs
twig.yaml should already exist, there is no need to create this file.
My suspicion is that if you created this file, you've created a file in the wrong place and Symfony is not picking up your configuration change. Instead, add your configuration change to the existing twig.yaml file under config/packages.
Once you add your custom exception_controller path to this existing (assumed default) twig.yaml it should look something like this:
twig:
default_path: '%kernel.project_dir%/templates'
debug: '%kernel.debug%'
strict_variables: '%kernel.debug%'
exception_controller: App\Controller\ExceptionController::showException
I tested this with a fresh install and it works as expected.
Hope this helps :)
Your method should be called showException and not endpoint as you defined in your twig.exception_controller configuration.

Did you try to use routing for routes ? Rooting

Related

No route found for "GET /Index" when generating Symfony controller

I am using generate:controller to create a new controller in my Symfony 3 application. But the route is not getting found.
Here is the input/output of the command ...
First, you need to give the controller name you want to generate.
You must use the shortcut notation like AcmeBlogBundle:Post
Controller name: ApplicationSonataPageBundle:Page
Determine the format to use for the routing.
Routing format (php, xml, yml, annotation) [annotation]: yml
Determine the format to use for templating.
Template format (twig, php) [twig]:
Instead of starting with a blank controller, you can add some actions now. An action
is a PHP function or method that executes, for example, when a given route is matched.
Actions should be suffixed by Action.
New action name (press <return> to stop adding actions): IndexAction
Action route [/Index]:
Template name (optional) [ApplicationSonataPageBundle:Page:index.html.twig]:
New action name (press <return> to stop adding actions):
Summary before generation
You are going to generate a "ApplicationSonataPageBundle:Page" controller
using the "yml" format for the routing and the "twig" format
for templating
Do you confirm generation [yes]?
... and here is the content of the new controller class:
namespace Application\Sonata\PageBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class PageController extends Controller
{
public function IndexAction()
{
return $this->render('ApplicationSonataPageBundle:Page:index.html.twig', array(
// ...
));
}
}
... which is not called. I instead receive the following error in the browser:
No route found for "GET /Index"
Is there an additional step I need to do before seeing my action?
What I have tried: I have so far tried every other type of routing (xml, php, yml) without success.
There are a couple of things to check:
Make sure your routes are included inside config/routes.yml
https://symfony.com/doc/3.3/routing.html
https://symfony.com/doc/3.3/routing.html#loading-routes
https://symfony.com/doc/3.3/routing/external_resources.html
Also make sure your bundle is loaded in the kernel: app/AppKernel.php
https://symfony.com/doc/3.3/page_creation.html#bundles-configuration
Another thing I notice, your action/route is capitalized. I'm not sure if this effects things but the common practice is camelCasing so you would have indexAction rather than IndexAction
There is also a command to show routes that are available I believe it is something like php bin/console routes:debug if you run php bin/console it should show you available commands
For what it's worth: I ended up just giving up and copying the following:
_index:
path: /Index
defaults: { _controller: ApplicationSonataPageBundle:Page:Index }
... from the generated yml file into my app's main routing.yml file.

How to add additional information (Host, URL, etc.) to Symfony/Monolog log output?

I am working on my first Symfony based WebApp project. I have configured Symfony to not only write log messages to the different log files but also to send critical error messages immediately as e-mail. This works fine. However I would like to add some additional information to the default log messages to make it easier to find the actual error source.
Example:
The Twig file of one pages loads the localized text from a .yml file. The texts contains an %about_link%placeholder that should be replaced by the route/URL to the About page. I forgot to this replacement, so the link did not point to an URL but to %about_link% instead. This leads to an NotFoundHttpException since no rout to %about_link% can be found...
No big deal. But to find the actual page/controller that contains this error was a bit tricky. The default log message shows the following:
[2015-12-14 17:19:36] request.ERROR: Uncaught PHP Exception Symfony\Component\HttpKernel\Exception\NotFoundHttpException: "No route found for "GET /%25about_link%25"" at /long/path/to/symfony/.../RouterListener.php line 176 []
So the exception was thrown in RouterListener.php when trying to find a route to %about_link%. Fine, this does not give me any hint on which page this bad link is located.
Of course the call to the bad route does not have to be located on any page at all. The user could have entered the bad link directly. Symfony would have to store/remember the last page to give any hint about the possible source. So, is it possible to include this information at all?
Additionally I would like to add information about the Host the problem was reported on. I am running two instances of the WebApp: www.my_web_app.xy and betatest.my_web_app.xy and it would be a great help, if the log message would show if it comes from www or from betatest.
Adding this information to log messages I create on myself is no problem, but how can I add this information to messages generated by Symfony or third party code? I would have to intercept the log message somehow before it reaches the log handler. Is this possible?
If you want to add extra information to log entries, you can do this with a processor. With a processor you can modify the record array, before it's parsed by a formatter. The extra part is shown at the end of the log entry.
<?php
namespace AppBundle\Monolog;
use Symfony\Component\HttpFoundation\RequestStack;
class WebProcessor
{
private $requestStack;
public function __construct(RequestStack $requestStack)
{
$this->requestStack = $requestStack;
}
public function processRecord(array $record)
{
$request = $this->requestStack->getCurrentRequest();
if ($request) {
$record['extra']['host'] = $request->getHost();
$record['extra']['url'] = $request->getRequestUri();
// ...
}
return $record;
}
}
Now add it to your services.yml to register it for all log entries:
app.monolog.processor.web:
class: AppBundle\Monolog\WebProcessor
arguments: ["#request_stack"]
tags:
- { name: monolog.processor, method: processRecord }
Don't reinvent the wheel! There is no need to write your own WebProcessor, since Monolog already has it.
The only thing you have to do is add it to your services and tag it with monolog.processor:
# app/config/services.yml
services:
Monolog\Processor\WebProcessor:
tags: ['monolog.processor']
Monolog has even more built-in processors you can use. I decided to add multiple processors in my application:
# app/config/services/monolog.yml (I included services/*.yml in config.yml)
services:
_defaults:
tags: ['monolog.processor']
Monolog\Processor\WebProcessor: ~
Monolog\Processor\GitProcessor: ~
Monolog\Processor\MemoryUsageProcessor: ~
Monolog\Processor\MemoryPeakUsageProcessor: ~
Monolog\Processor\IntrospectionProcessor: ~
You can use a custom formatter to change the output written to the monolog log files. You can find more information about this subject here: http://symfony.com/doc/current/cookbook/logging/monolog.html#changing-the-formatter
Short version: you can create a custom formatter class that implements Monolog\Formatter\FormatterInterface and you can enable it in your config.yml file this way:
# app/config/config.yml
services:
my_formatter:
class: Monolog\Formatter\JsonFormatter
monolog:
handlers:
file:
type: stream
level: debug
formatter: my_formatter

Need Assistance with Symfony 2.7 creating first page

I am trying to learn the Symfony framework and struggling with it. The instructions are not very helpful or assume I know a lot more than I know. I am just trying to create a single web page with proper route and controller. I have been googling to find answers and made some progress but no luck yet. Right now I just have the standard install of Symfony with just default bundles etc. I created a project called "gtest3" and chose PHP for it...
I am not sure where I put the new route in (what file) or maybe it needs to be put in more than one file?
I found the "routing.yml" file which seems that is where I need to put it...
here is what is in there right now:
gtest3:
resource: "#gtest3Bundle/Resources/config/routing.php"
prefix: /
app:
resource: "#AppBundle/Controller/"
type: annotation
I am guessing I need to add something to this and put the location/filename of the controller? I have tried doing this a few ways and just get errors.
There is also the "routing.php" file that is referenced in the above code. I am not sure if this is the "controller" or if it is an additional piece of the "route". Here is the code from that file:
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
$collection = new RouteCollection();
$collection->add('gtest3_homepage', new Route('/hello/{name}', array(
'_controller' => 'gtest3Bundle:Default:index',
)));
return $collection;
I am not sure what if anything I would add here.
Finally - there is the "DefaultConroller.php" file I found as well which may also be the controller. I dont think I need to include the code of that file here.
So - all I am trying to do is create a route of maybe "/gman" and then have the controller just echo something on the page. Super basic stuff. And I cannot figure out how to get this going.
Can anyone help with this? Thanks so much...
You can define your routes in three ways, either by using yml files, xml files, or by using a php file. This is documented behaviour.
You are from the looks of your routing.yml trying to set up a php version. I would not recommend it, and instead use configuration over coding the routing.
The annotation example would look like:
Adding a controller:
namespace Gtest3Bundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
class Gtest3Bundle extends Controller
{
/**
* #Route("/hello/{name}")
* #Template()
*/
public function indexAction($name)
{
return array('name' => $name);
}
}
And add in your app/config/routing.yml:
gtest3:
resource: "#Gtest3Rights/Controller/"
type: annotation
prefix: /what-ever-you-want
You can check what kind of routes you have defined by using:
./app/console router:debug
If it doesn't appear hear, you have something misconfigured.
Please be advised that your bundle names breaks the convention of how bundles should be named in the symfony2 context.
It is advised to use NamespaceProjectBundle. This also documented. If you are stuck, try generating a bundle via the ./app/console generate:bundle. This way you can create a whole symfony2 structure which should show the default page hello/foo page just fine.
If it doesn't seem to run at all, make sure you have registered your bundle at the in the app/AppKernel.php file in the registerBundles() method.
To configure routes you can use yml, php or xml file. You can specify it in app/config/config.yml
framework:
router:
resource: "%kernel.root_dir%/config/routing.yml"
It's where you can check which file is used now.
There are some manners to store the routes.
app:
resource: "#AppBundle/Controller/"
type: annotation
This is how you use routes by writing annotations above your actions (eg indexAction) inside your controller class. Read more.
Another common approach is to build one or more .yml files inside each Bundle.
in app/config/routing.yml you should write this:
app:
resource: "#AppBundle/Resources/config/routing.yml"
prefix: /
Then you need to create the file (and directories if necessary) src/AppBundle/Resources/config/routing.yml and add the following content:
app_homepage:
path: /
defaults: { _controller: AppBundle:Default:index }
It will then try to find the DefaultController and fires the indexAction in the AppBundle (src/AppBundle/Controller/DefaultController.php).
To debug your routes simply type in your console from your projects directory:
app/console router:debug

Symfony cannot find the template file

I have follow all the steps related to Symfony installation, and I try the examples of the Symfony book (provided by the Symfony web site). Currently I am on Controllers chapter (5) and I try the following code:
namespace MyBundle\FrontBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class HelloController extends Controller
{
public function indexAction($name, Request $request)
{
return $this->redirect($this->generateUrl('front_buy'), 301);
}
public function buyAction(Request $request)
{
return $this->render(
'Hello/buy.html.twig',
array(
'name' => 'Nikos'
)
);
}
}
but I get the following error:
INFO - Matched route "front_buy" (parameters: "_controller": "MyBundle\FrontBundle\Controller\HelloController::buyAction", "_route": "front_buy")
CRITICAL - Uncaught PHP Exception InvalidArgumentException: "Unable to find template "Hello/buy.html.twig"." at /var/www/projects/symfony/vendor/symfony/symfony/src/Symfony/Bridge/Twig/TwigEngine.php line 128
Context: {"exception":"Object(InvalidArgumentException)"}
I know is not something fancy, but I don't know how to fix the problem.
My view file is under the following path : ./src/MyBundle/FrontBundle/Resources/views/Hello/buy.html.twig.
You need to render it with the following syntax:
$this->render('AcmeBlogBundle:Blog:index.html.twig')
or with this syntax
$this->render('#BlogBundle/Blog/index.html.twig')
An Example:
$this->render('#FrontBundle/Hello/buy.html.twig)
More information can be found on the documentation, also refering to symfonys best practices templates should be stored in app/Ressources/views
in "app/config/config.yml" be sure to have this:
framework:
# ...
templating:
engines: ['twig']
In my case, the problem was really related to the specific version of Symfony.
My project used to be run with Symfony 2.8.19. I tried to migrate it to another Linux
evironment (uning symfony2.8.42) and then I got the very same error with the same code (very wierd).
I tried the solutions mentioned before and none worked like using :
$this->render('#BlogBundle/Blog/index.html.twig')
or
$this->render('AcmeBlogBundle:Blog:index.html.twig').
After several tries, I found the problem. In fact, in my old env, I had :
return $this->render('XxxxxBundle:Default:zzzz.html.twig';
But the problem was with Capitalized Default because the real path was with an uncapitalized default
so changing it to the following fixed the problem in my new env:
return $this->render('XxxxxBundle:default:zzzz.html.twig';

Routes not working in FOSRestBundle and Symfony

I've been going round in circles with this one. I've been either getting 500 errors saying template cannot be rendered or found, or when I attempt to use the annotations, they clash with the fact I'm using Symfony's annotations for my routes. With the current code, I'm just getting 404's.
My config:
# config.yml
fos_rest:
routing_loader:
default_format: json
An example of my controller:
namespace IGIG\GigBundle\Controller;
use FOS\RestBundle\Controller\FOSRestController;
use FOS\RestBundle\Controller\Annotations\Route;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use IGIG\GigBundle\Document\Gig;
class GigApiController extends FOSRestController
{
public function getGigsAction()
{
$gigs = $this->get('doctrine_mongodb')
->getRepository('IGIGGigBundle:Gig')
->findAll();
$view = $this->view($gigs, 200)
->setTemplate("IGIG:GigBundle:getGigs.html.twig")
->setTemplateVar('gigs');
return $this->handleView($view);
}
}
Routing
gigs:
prefix: /api
type: rest
resource: IGIG\GigBundle\Controller\GigApiController
I should also add, the .html.twig file within the controller doesn't actually exist, I was under the impression that it was automatically generated, is that the case?
Thanks in advance!
First of all it looks like your config is not indented properly, but might also just be a copy/paste error, otherwise it should throw an exception for you.
# config.yml
fos_rest:
routing_loader:
default_format: json
I should also add, the .html.twig file within the controller doesn't actually exist, I was under the impression that it was automatically generated, is that the case?
No, you do need to generate that template file yourself and that is probably the cause for your 500 errors. However if you don't intend to use twig templates next to your REST API, so if you ever only want to return JSON responses, then you won't need them at all and can remove the calls from your controller too.
For your 404's: do a ./app/console router:debug | grep api and see if the generated routes are like what you expect.
You should have a look at the bundle documentation again, in particular the full config reference: https://github.com/FriendsOfSymfony/FOSRestBundle/blob/master/Resources/doc/configuration-reference.md
And I found this very helpful too when starting out with REST APIs with Symfony: http://welcometothebundle.com/symfony2-rest-api-the-best-2013-way/

Categories