overridden in Symfony 2 error customization? - symfony

I am working on error pages in symfony2 but I am not successful in override this template.
Can any one describe it How I can override all exception pages. I want three pages error.html.twig , 403.html.twig, 404.html.twig
I do this way:
first create file in this position:
app/Resources/TwigBundle/views/Exception
app/Resources/TwigBundle/views/layout.html.twig
I put all twig exceptions file in Exception folder and write some custom code.
But I am some time success and some time got blank pages.
And this page is working in dev env but in prod env not show.
I want when error then error page , if 404 then 404 page error, if forbidden then 403 page.
Any one describe me or tell me how I can do this.
If write some code It's good for me ?
In other think I am all problem handle through RedirectExceptionListner service but I do not do this because this is redirect to error pages.
Thanks!

Just create error + number of error + .hmlt.twig in app/Resources/TwigBundle/views/Exception.
For the 404, the file would be error404.html.twig.
Hope it helps.

There are two steps to override error pages.
First of all: Follow tutorial on this page: http://symfony.com/doc/current/cookbook/controller/error_pages.html. In app/Resources/TwigBundle/views/Exception create file error.html.twig. You can also create error404.html.twig and other error pages. Content of the file is your decision.
Second step is to add assetic in your config.yml
assetic:
bundles: ['TwigBundle']
Without that you will get blank pages.
And of course, don't forget to clear the cache and reinstall assetics:
php app/console assetic:dump --env=prod --no-debug
How to know which error twig will be rendered? For me, the best solution is to create method in controller like:
function findQuestionOr404($questionId)
{
$survey = $this
->getDoctrine()
->getRepository('MyGreatBundle:Question')
->find($questionId)
;
if (!$survey) {
throw $this->createNotFoundException());
}
return $survey;
}
And then in action:
public function someAction()
{
$queston = $this->findQuestionOr404($id);
//...
}
This will throw 404 error (if there is no survey with particullar $id) and show error404.html.twig. Of course, you're free to throw any Exception class in your controller.

Related

Can I enable exceptions on warnings in production?

Just like in debug mode, I'd like Symfony to catch any notice or warning in my prod environment, and convert it to an exception.
Can I do this without enabling the whole debug mode?
Symfony already catches exceptions, the difference between DEV and PROD (in their default configuration) is that DEV shows you a 500 error page with stack trace and all details, while PROD shows you a "silent" 500 error page.
That is intended: You should not expose those details in production.
If your production instance is safe (e.g. used internally) you may choose one the following two options.
Enable debug mode: in your .env or .env.local file on the server, set:
APP_DEBUG=true
This is probably the closest answer to your original question.
Use dev Symfony mode: in your .env or .env.local file on the server, set:
APP_ENV=dev
This also changes other behaviours (e.g. more detailed logs, include other configuration files). See https://symfony.com/doc/current/configuration.html#configuration-environments for additional details.
Indeed you can catch PHP warnings and convert them to exceptions in production (not sure if this makes sense for notices but you can also do it for notices).
Basically the question is old and was already discussed in detail: Can I try/catch a warning?
Just setup your own error handler (https://www.php.net/manual/en/function.set-error-handler.php) with a custom event listener on kernel.request (which is always called very early) (https://symfony.com/doc/current/reference/events.html#kernel-request):
namespace App\EventListener;
use Symfony\Component\HttpKernel\Event\RequestEvent;
class ProdWarningToExceptionListener {
private $environment;
public function __construct(KernelInterface $kernel)
{
$this->environment = $kernel->getEnvironment();
}
public function onKernelRequest(RequestEvent $event)
{
if ($this->environment === "prod") {
set_error_handler(function($errno, $errstr, $errfile, $errline) {
// $errno contains the error level, do with it whatever you want
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
});
}
}
}
Note that this is pseudo-code, you might have to adjust it a little bit. But basically it should solve your problem.
https://symfony.com/doc/current/reference/configuration/framework.html#php-errors
config/packages/framework.yaml
framework:
....
php_errors:
throw: true

SYMFONY3 in prod look for TWIG template in wrong folder instead of custom bundle indicated in routing.yml and AppKernel.php

I am implementing a SYMFONY 3 project in production mode for the first time.
I follow OceanDigital tutorial and the standard doc.
I went thru a bunch of issues linked to user writing rights that I've solved, and I do get now a SYMFONY ERROR page (one step closer to victory) with this message:
Unable to find template "MyBundle:std_page:home.html.twig" (looked
into: /[folder to symf project]/app/Resources/views,
/[folder to symf project]/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Resources/views/Form,
/[folder to symf project]/vendor/knplabs/knp-menu/src/Knp/Menu/Resources/views).
If I look in my [my symf project]\app\config\routing.yml, I have:
my_bundle:
resource: "#MyBundle/Resources/config/routing.yml"
options:
expose: true
In [my symf project]\app\AppKernel.php, in the registerBundles() function, I have:
class AppKernel extends Kernel
{
public function registerBundles()
{
$bundles = [
....
new MyBundle\MyBundle(),
.....
]
}
}
And the file regarding the template that should be fetched [my symf project]\src\MyBundle\Ressources\views/std_page/home.html.twig exists.
What did I not set up right, in production mode, to have it looking for the TWIG template in the folder [my symf project]\src\MyBundle\Ressources\views/?
After some search it happens to be a mistake similar to the one described in that SO thread.
In my controller I had:
return $this->render('MyBundle:Std_page:home.html.twig',$parameters);
Instead of:
return $this->render('MyBundle:std_page:home.html.twig',$parameters);
The development was made on a WINDOWS 10 OS, and it is set up in production on a UBUNTU 16.04. It seems that UBUNTU is stricter than WINDOWS regarding the letter case.

Symfony2 and production environment - allways displays app_dev in links

I have a symfony2 project running with nginx and the problem is that when accessing the prod environment, all the links are still with app_dev.php there.
Here are my config files:
app.php
<?php
require_once __DIR__.'/../app/bootstrap.php.cache';
require_once __DIR__.'/../app/AppKernel.php';
use Symfony\Component\HttpFoundation\Request;
$kernel = new AppKernel('prod', false);
$kernel->loadClassCache();
$kernel->handle(Request::createFromGlobals())->send();
The links in the twig file are called this way:
Route name: user_login, in twig: user_login_path()
Where could the problem come from? Nginx?
You should always use path('route_name') in order to generate links or actions. It seems that the function(s) you are using (kind of twig extension) is bad coded and server dependent. But it does not comes with Symfony itself.
You have multiple options :
The cleanest : replace every href, action, ... with the path function
A (maybe) faster one : find the custom twig extension and make it work (more likely in src/Acme/MyBundle/Twig/MyExtension.php)
A quick and dirty one : rewrite every app_dev.php urls to app.dev with a .htaccess (not really recommended at all but... well...)

Assetic Route Not Found

I have a twig extension whose purpose is to collect a list of CSS and JS file paths given to it by function calls throughout a template hierarchy and then at the end of the twig template to take the output buffer and include these files in the <head> section of the page. For the most part it has been straightforward to implement.
In my service definition for the twig extension I am injecting the assetic.helper.dynamic service into it. The problem is when I call the javascripts() or stylesheets() method to get a URL for a CSS or JS file I get an error like this:
An exception has been thrown during the rendering of a template ("None
of the chained routers were able to generate route: Route
'_assetic_bd311c7' not found")
service.yml:
admin.twig.asset_extension:
class: Zing\Delta\AdminBundle\Twig\AssetExtension
tags:
- { name: twig.extension }
arguments: ['#assetic.helper.dynamic']
In my extension I am essentially doing this to get the URL for an asset:
$assetic_helper->stylesheets(array(
'#SomeBundle/Resources/public/js/jquery.tablesort.min.js'
));
I don't understand why the router can't find the routes or why assetic is setting up the routes.
The fix ended up being to run the following commands in the following order from the project root.
$ php app/console assets:install
$ php app/console assetic:dump
$ php app/console cache:clear

User Friendly Error page in Symfony2

Whenever I am getting error like Fatal error: Call to a member function getName() on a non-object in /var/www/...Controller.php on line 143, My symfony2-app shows a blank page in prod-environment. The above message available in dev-environment. I want to show a custom page in prod-environment for such errors. How can I implement it in Symfony2?
Update:
May kernel.event_listener help me?
You cannot really implement that in symfony. Fatal errors are not handled by symfony but by the PHP extension itself. The Symfony code never gets a chance to finish executing because of the fatal error leaving php to handle the error by its own devices. PHP error handling is set by error_reporting() and the error_handler set by set_error_handler(). In the dev environment, php error reporting is set to E_ALL to show all errors. In a production environment, errors and debug messages are set to 0 and are not displayed for aesthetic and security reasons (some error messages may display password, etc). The best advice would be to fix all fatal errors before deploying to production. To catch and display a custom page for fatal errors must be done using php set error handling - http://php.net/manual/en/function.set-error-handler.php.
For non-fatal errors, you can create a custom error page view that can be displayed - http://symfony.com/doc/2.0/cookbook/controller/error_pages.html
I do it this way:
class ErrorExceptionHandler {
function __construct() {
register_shutdown_function(array($this, 'fatalErrorHandler'));
}
function fatalErrorHandler() {
$error = error_get_last();
if ($error['type'] === E_ERROR) {
header('Location: /error-page-url');
}
}
}
ErrorExceptionHandler(); // add to app.php
Of course please remember about namespace etc.

Resources