Can I enable exceptions on warnings in production? - symfony

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

Related

symfony4 migrate autowire to true - get error message

I am migrating from symofony 2.7 to symfony 4.0. With success I migrated one bundle. Now I am migrating the second bundle and the error message is coming up. I don't get at all what symfony 4.0 wants from me.
If I turn on autowire: true this error message is coming up.
Cannot autowire service "App\Kernel": argument "$environment" of method "Symfony\Component\HttpKernel\Kernel::__construct()" must have a type-hint or be given a value explicitly.
Can somebody help me?
If I turn it off, no message is coming up.
Update
I registered my bundle only in bundles.php
App\Backend\AccountBundle\BackendAccountBundle::class => ['all' => true],
Usually the Kernel is added to the Service Container as a so called synthetic service, meaning it's not generated by the DI-container from configuration. Rather the id is set and then the previously configured service is just added to the container. It seems rather odd that your bundle's container wants to create a new kernel here. So I would check where and how you want to access the kernel in any of the bundle's services and whether you actually want to pass in the kernel and not something else. If you do you might want to check the Service Container-documentation on synthetic services.
As to the error itself. Symfony's autowiring often falls flat when you have services that require parameters like with the Kernel:
public function __construct(string $environment, bool $debug) {...}
In these cases you have to either have a parameter defined in your services.yaml that matches the name of the parameter:
# config/services.yaml
parameters:
environment: prod
debug: false
or you have to tell the configuration which parameters you want to have in those places.
App\Kernel:
$environment: prod
$debug: false
This will tell the autowiring that only the 2 arguments named environment and debug should be overwritten with the values you provide, but the rest is done via autowiring. This way you can skip the arguments: part of the definition and you can also skip all arguments you know are correctly set via autowiring.
For example if you have a service like this:
class MyService {
public function __construct(OtherServce $service, string $someParameter) {}
}
# config/services.yaml
services:
_defaults:
autowiring: true
MyService:
$someParameter: 'someValue'
This is the same as explicitly writing:
services:
MyService:
class: MyService
arguments:
- '#OtherServce'
- 'someValue'

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.

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.

ReactJS.NET - Bundles - TinyIoCResolutionException: Unable to resolve type: React.IReactEnvironment

I'm attempting to minify my .JSX files with ASP.NET Minification and Optimization via System.Web.Optimization.React. I've installed the MVC4 React Package as well as the Optimization package, but whenever I try to include a bundle I get the following:
React.TinyIoC.TinyIoCResolutionException: Unable to resolve type: React.IReactEnvironment
The InnerException is always null
My bundles are setup as follows:
bundles.Add(new ScriptBundle("~/Bundle/Scripts/ReactJS").Include(
"~/Scripts/React/react-0.12.2.js",
"~/Scripts/React/react-with-addons-0.12.2.js",
"~/Scripts/React/JSXTransformer-0.12.2.js"
));
bundles.Add(new JsxBundle("~/Bundle/Scripts/ReactCalendar").Include(
"~/Scripts/React/Calendar/Main.react.jsx",
"~/Scripts/React/Calendar/Components/Calendar.react.jsx",
"~/Scripts/React/Calendar/Components/CalendarEvent.react.jsx",
"~/Scripts/React/Calendar/Components/CalendarControls.react.jsx",
"~/Scripts/React/Calendar/Components/CalendarTimeSlots.react.jsx"
));
And included in the view as:
#section scripts{
#Scripts.Render("~/Bundle/Scripts/ReactJS");
#Scripts.Render("~/Bundle/Scripts/ReactCalendar");
}
The error is always thrown on line:
#Scripts.Render("~/Bundle/Scripts/ReactCalendar");
Anyone got any ideas on how to solve / debug this one? Let me know if more info is needed.
I'm not sure if this is the same issue I was facing, but I googled the exact same error, found this SO topic as the first hit, with no definitive answer, so I thought I'd offer my solution.
I'm using .NET 4.5 in an MVC app, and React.Web.Mvc4 v3.0.0.
I managed to work around this issue with the help of this comment on Github.
Here's my entire ReactConfig.cs:
using React;
using React.TinyIoC;
using React.Web.TinyIoC;
namespace NS.Project
{
public static class ReactConfig
{
public static void Configure()
{
Initializer.Initialize(AsPerRequestSingleton);
ReactSiteConfiguration.Configuration
.SetLoadBabel(false)
.AddScriptWithoutTransform("~/React/dist/server.bundle.js");
}
private static TinyIoCContainer.RegisterOptions AsPerRequestSingleton(
TinyIoCContainer.RegisterOptions registerOptions)
{
return TinyIoCContainer.RegisterOptions.ToCustomLifetimeManager(
registerOptions,
new HttpContextLifetimeProvider(),
"per request singleton"
);
}
}
}
Then, I'm callingReactConfig.Configure explicitly from Application_Start.
"Unable to resolve type: React.IReactEnvironment" with no InnerException generally means ReactJS.NET is not initialising properly for some reason. In web apps, ReactJS.NET handles initialisation through the use of WebActivator. Make sure your project is referencing React.Web, React.Web.Mvc4 and WebActivatorEx, and all the corresponding .dll files are ending up in your app's bin directory.
Also, you do not need to (and should not) include JSXTransformer in your JavaScript bundles, as ReactJS.NET does all the JSX compilation server-side.
Something looks like changed from React.Web.MVc4 version 4.0.0. versions before didnt have that problem.
as stated here
Install the React.Web.Mvc4 package through NuGet. You will also need to install a JS engine to use (either V8 or ChakraCore are recommended). See the JSEngineSwitcher docs for more information.
To use V8, add the following packages:
JavaScriptEngineSwitcher.V8
JavaScriptEngineSwitcher.V8.Native.win-x64
ReactConfig.cs will be automatically generated for you. Update it to register a JS engine and your JSX files:
using JavaScriptEngineSwitcher.Core;
using JavaScriptEngineSwitcher.V8;
[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(React.Sample.Mvc4.ReactConfig), "Configure")]
namespace React.Sample.Mvc4
{
public static class ReactConfig
{
public static void Configure()
{
ReactSiteConfiguration.Configuration
.AddScript("~/Content/Sample.jsx");
JsEngineSwitcher.Current.DefaultEngineName = V8JsEngine.EngineName;
JsEngineSwitcher.Current.EngineFactories.AddV8();
}
}
}
If anyone needs this, just install this nuget and it will resolve this issue.
System.Web.Optimization.React

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