User Friendly Error page in Symfony2 - symfony

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.

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

Sudden syntax error after deployment

I have a working symfony project. I have it on a private bitbucked repository and locally the website works without an issue.
Today I tried to deploy the project onto an external server linuxpl.com.
Steps taken include:
Istalling composer
Adding the mysql database
Running git clone to get the data into a proper location
Running composer install on the folder to install everything and connect to the db
Cleared the cache
Set the project root as ....domain/project_name/web
However after completing all these steps, when running the website with regular server:run I'm getting this odd error:
Parse error: syntax error, unexpected '.' in /home/spirifer/domains/surowcewobiektywie.pl/konkurs/vendor/twig/twig/lib/Twig/Extension/Core.php on line 1571
Not sure if this is of any importance but the mentioned code partion looks like this in my local files:
// Some objects throw exceptions when they have __call, and the method we try
// to call is not supported. If ignoreStrictCheck is true, we should return null.
try {
$ret = $object->$method(...$arguments);
} catch (BadMethodCallException $e) {
if ($call && ($ignoreStrictCheck || !$env->isStrictVariables())) {
return;
}
throw $e;
}
The local version does not differ from the one on the server.
My local machine has PHP 7.0.9 and the remove server has PHP 7.0.14
How could I fix this issue?
PHP 5.6 adds Variadic functions, with "...". However, Twig v1.x only required the use of PHP 5.2.7 or above.
If you didn't explicitly update to Twig 2.0, it's very possible you have used the 'death star' version constraint in the composer file - '*'. which allows uncontrolled version updates to the latest version. If this is the case, you will need to either update your version of PHP, or at least require just a previous version of Twig/twig, "^1.32" would be the latest in the version 1 series of Twig.

Symfony2 Automatically HTTP Cache Clearing

Hi All
Recently we migrated to symfony2 application. Now I am having a problem with storage on the systems. The system is running on the docker container. It looks like application is not deleting the http_cache automatically. After searching in the internet found few following solutions. But not sure about the actual problem.
Solution 1
// app/AppCache.php
use Symfony\Bundle\FrameworkBundle\HttpCache\HttpCache;
class AppCache extends HttpCache
{
protected function getOptions()
{
return array(
'default_ttl' => 500,
// ...
);
}
}
This looks like a solution, but not really able to test it on local system.
Solution 2
Periodically run following command via cron job or similar to clear the cache.
php app/console cache:clear --env=prod
Hints
I am getting following error on the server, but it is not too often. I am not sure if it is the real issue that is causing system to crash.
[xx-xxx-xxxx xx:xx:xx] WARNING: [pool www] child 2452 said into stderr: "NOTICE: PHP message: PHP Notice: SessionHandler::gc(): ps_files_cleanup_dir: opendir(/var/lib/php/sessions) failed: Permission denied (13) in /var/www/vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Session/Storage/Proxy/SessionHandlerProxy.php on line 93"
Server Setup
The application is running on docker container.
Any help or hint would be great,am I missing anything?

Call to undefined method RegistrationController::getEngine() in

Everything worked fine. And then suddenly started getting this error.
On the local computer.
FatalErrorException: Error: Call to undefined method Adwordsup\SecurityBundle\Controller\RegistrationController::getEngine() in /var/www/adwords-up/src/Adwordsup/SecurityBundle/Controller/RegistrationController.php line 68
On hosting all is well. Compared. Noticed a difference only that the different structures.
Local: friendsofsymfony/userbundle/
Hosting: friensofsymfony/userbundle/FOS/UserBundle/
Extension possible after updating the bundle flew. What could be the problem?
The getEngine() method has been removed. I Just pass the extension of my template statically (.twig for example).
The getEngine() method has been removed. You can do the following in your controller and it will work:
return $this->render('yourtemplatename.html.twig', $array);

overridden in Symfony 2 error customization?

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.

Resources