Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error Massage showes DB Connection Parameter (host, user, password) in the frontend #1422

Closed
jommbee opened this issue Mar 12, 2018 · 29 comments
Assignees
Labels
Milestone

Comments

@jommbee
Copy link

jommbee commented Mar 12, 2018

Contao 4.4.16

Following Error Massage was shown in the frontend:

Fatal error: Uncaught PDOException: SQLSTATE[HY000] [2002] No such file or directory in 
/www/XXX/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:43 Stack trace: #0 
/www/XXX/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php(43): PDO->__construct
('mysql:host=HOST, 'USER', 'PASSWORT', Array) #1 
/www/XXX/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php(44): Doctrine\DBAL\Driver
\PDOConnection->__construct('mysql:host=HOST', 'USER', 'PASSWORT', Array) #2 
/www/XXX/vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php(372): Doctrine\DBAL\Driver\PDOMySql\Driver->connect(Array, 'USER', 'PASSWORT', Array) #3 
/www/XXX/vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php(432): Doctrine\DBAL\Connection->connect() #4 /www/XXX in /www/XXX/vendor/doctrine/doctrine-bundle/ConnectionFactory.php on line 
96

Luckily in a password-protected environment. On a live page, this would be a disaster.

Error Messages log file:

[2018-03-12 17:11:44] request.CRITICAL: Uncaught PHP Exception Doctrine\DBAL\DBALException: "An exception occured while establishing a connection to figure out your platform version. You can circumvent this by setting a 'server_version' configuration value For further information have a look at: https://github.com/doctrine/DoctrineBundle/issues/673" at /www/XXX/vendor/doctrine/doctrine-bundle/ConnectionFactory.php line 96 {"exception":"[object] (Doctrine\\DBAL\\DBALException(code: 0): An exception occured while establishing a connection to figure out your platform version.\nYou can circumvent this by setting a 'server_version' configuration value\n\nFor further information have a look at:\nhttps://github.com/doctrine/DoctrineBundle/issues/673 at /www/XXX/vendor/doctrine/doctrine-bundle/ConnectionFactory.php:96, Doctrine\\DBAL\\Exception\\ConnectionException(code: 0): An exception occurred in driver: SQLSTATE[HY000] [2002] No such file or directory at /www/XXX/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractMySQLDriver.php:108, Doctrine\\DBAL\\Driver\\PDOException(code: 2002): SQLSTATE[HY000] [2002] No such file or directory at /www/XXX/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:47, PDOException(code: 2002): SQLSTATE[HY000] [2002] No such file or directory at /www/XXX/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:43)"} []

[2018-03-12 17:11:44] request.CRITICAL: Exception thrown when handling an exception (Doctrine\DBAL\DBALException: An exception occured while establishing a connection to figure out your platform version. You can circumvent this by setting a 'server_version' configuration value For further information have a look at: https://github.com/doctrine/DoctrineBundle/issues/673 at /www/XXX/vendor/doctrine/doctrine-bundle/ConnectionFactory.php line 96) {"exception":"[object] (Doctrine\\DBAL\\DBALException(code: 0): An exception occured while establishing a connection to figure out your platform version.\nYou can circumvent this by setting a 'server_version' configuration value\n\nFor further information have a look at:\nhttps://github.com/doctrine/DoctrineBundle/issues/673 at /www/XXX/vendor/doctrine/doctrine-bundle/ConnectionFactory.php:96, Doctrine\\DBAL\\Exception\\ConnectionException(code: 0): An exception occurred in driver: SQLSTATE[HY000] [2002] No such file or directory at /www/XXX/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractMySQLDriver.php:108, Doctrine\\DBAL\\Driver\\PDOException(code: 2002): SQLSTATE[HY000] [2002] No such file or directory at /www/XXX/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:47, PDOException(code: 2002): SQLSTATE[HY000] [2002] No such file or directory at /www/XXX/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:43)"} []

@aschempp
Copy link
Member

aschempp commented Mar 13, 2018 via email

@jommbee
Copy link
Author

jommbee commented Mar 13, 2018

I didn't call the page via app_dev. php. So I didn't worked in debug mode.
Normal working in the Backend, then Server error 500. After/while that the error above was shown in Frontend.

@Xirdion
Copy link

Xirdion commented Mar 13, 2018

If you didn't call the page via app_dev.php maybe you changed the app.php to run in environment-mode so that error-messages are shown in the frondend?

@jommbee
Copy link
Author

jommbee commented Mar 13, 2018

Did no changes on app.php

@leofeyer
Copy link
Member

leofeyer commented Mar 13, 2018

I cannot reproduce the issue. The manager bundle has a workaround for this case, therefore I see the pretty error screen if I manually stop the MySQL service.

@leofeyer
Copy link
Member

I have tried it with Contao 4.4.16 and 4.5.6 and I never saw the error message, neither with wrong DB credentials nor with the MySQL service being stopped manually.

@fritzmg
Copy link
Contributor

fritzmg commented Mar 13, 2018

I can reproduce it in Contao 4.4.16 in the front end and the login page:

Fatal error: Uncaught PDOException: SQLSTATE[HY000] [2002] No connection could be made because the target machine actively refused it. 
in C:\xampp\htdocs\c44dev\vendor\doctrine\dbal\lib\Doctrine\DBAL\Driver\PDOConnection.php:43 Stack trace:
#0 C:\xampp\htdocs\c44dev\vendor\doctrine\dbal\lib\Doctrine\DBAL\Driver\PDOConnection.php(43): PDO->__construct('mysql:host=loca...', 'root', '', Array)
#1 C:\xampp\htdocs\c44dev\vendor\doctrine\dbal\lib\Doctrine\DBAL\Driver\PDOMySql\Driver.php(41): Doctrine\DBAL\Driver\PDOConnection->__construct('mysql:host=loca...', 'root', '', Array)
#2 C:\xampp\htdocs\c44dev\vendor\doctrine\dbal\lib\Doctrine\DBAL\Connection.php(360): Doctrine\DBAL\Driver\PDOMySql\Driver->connect(Array, 'root', '', Array)
#3 C:\xampp\htdocs\c44dev\vendor\doctrine\dbal\lib\Doctrine\DBAL\Connection.php(429): Doctrine\DBAL\Connection->connect()
#4 C:\xampp\htdocs\c44dev\vendor\doctrine\dbal\lib\Doctrine\DBAL\Connection.php(389): Doctrine\DBAL\Connection->getDatabasePlatformVersion()
#5 C:\xampp\htdocs\c44dev\vendor\d in C:\xampp\htdocs\c44dev\vendor\doctrine\doctrine-bundle\ConnectionFactory.php on line 96

@leofeyer
Copy link
Member

That's great, but how?

@fritzmg
Copy link
Contributor

fritzmg commented Mar 13, 2018

I only disabled the MySQL server, nothing more.

In Contao 4.5.6 I only see the following after disabling the MySQL server:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>An Error Occurred: Not Found</title>
    </head>
    <body>
        <h1>Oops! An Error Occurred</h1>
        <h2>The server returned a "404 Not Found".</h2>

        <div>
            Something is broken. Please let us know what you were doing when this error occurred.
            We will fix it as soon as possible. Sorry for any inconvenience caused.
        </div>
    </body>
</html>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>An Error Occurred: Internal Server Error</title>
    </head>
    <body>
        <h1>Oops! An Error Occurred</h1>
        <h2>The server returned a "500 Internal Server Error".</h2>

        <div>
            Something is broken. Please let us know what you were doing when this error occurred.
            We will fix it as soon as possible. Sorry for any inconvenience caused.
        </div>
    </body>
</html>

@leofeyer
Copy link
Member

Really? I cannot reproduce this either. You should probably delete the cache folders.

@fritzmg
Copy link
Contributor

fritzmg commented Mar 13, 2018

I have executed the following:

composer install

and then made a front end request. Still the same.

// nvm, suddenly I see the regular error page in Contao 4.5.6... weird.

My guess is that it also makes a difference if the target machine actively refuses the connection or if a timeout happens.

@jommbee
Copy link
Author

jommbee commented Mar 13, 2018

My System runs on allinkl server. Now try to find out what the problem was there.

@jommbee
Copy link
Author

jommbee commented Mar 13, 2018

Support von Allinkl beschreibt den Vorfall wie folgt:

gestern kam es zu der angegeben Zeit zu einer Überlastung des Servers.
Das Monitoring wertet hier zum Beispiel die Load und Speicherauslastung aus und startet ggf die Dienste neu oder meldet dies der Technik.
Dabei wurde der MySQL-Dienst neugestartet, um Fehler und Beschädigungen der Tabellen zu vermeiden

So it`s a common situation that can happen at any time.

@leofeyer
Copy link
Member

Ok, I finally figured out how to reliably reproduce this.

  • Start the MySQL service
  • Run cache:clear -e prod which will build the cache
  • Stop the MySQL sevice
  • Open the front end

They problem is that our workaround is only applied if the DB connection fails upon container build. If the container is built successfully and the DB connections goes away later, the error message is shown.

Possible solution: Permanently add the server_version variable in the doctrine.yml (Contao 4.4) or config.yml (Contao 4.5) file. Drawback: The server version might differ from the actual server version. I don't know how Doctrine uses the variable though. @contao/developers Do you know?

@leofeyer leofeyer added the bug label Mar 13, 2018
@leofeyer leofeyer added this to the 4.4.17 milestone Mar 13, 2018
@ausi
Copy link
Member

ausi commented Mar 13, 2018

I don’t think the error itself is the problem. It is expected that the website breaks if the database goes away.

Instead of fixing the error, I think we should check why the error message gets printed instead of the pretty error screen.

@leofeyer
Copy link
Member

leofeyer commented Mar 13, 2018

Here is another possible solution in the Plugin.php file of the manager bundle:

$server_version = '5.1';

try {
    $connection = DriverManager::getConnection($params);

    if ($connection->getDatabasePlatform() instanceof MySQL57Platform) {
        $server_version = '5.7';
    }
} catch (DriverException $e) {
    // ignore
}

$extensionConfigs[] = [
    'dbal' => [
        'connections' => [
            'default' => [
                'server_version' => $server_version,
            ],
        ],
    ],
];

Instead of only setting the server version if the connection fails, it is now always stored in the container.

@leofeyer
Copy link
Member

Instead of fixing the error, I think we should check why the error message gets printed instead of the pretty error screen.

That's a point for sure. But I think we failed to do so last time, which is why we have implemented the workaround in the Plugin class.

@leofeyer
Copy link
Member

Also setting the server_version variable is the recommended "fix" for this problem:

@leofeyer
Copy link
Member

leofeyer commented Mar 13, 2018

I had to adjust the fix to be forward compatible with the upcoming MariaDb1027Platform class in Doctrine.

/** @var ServerInfoAwareConnection $connection */
$connection = DriverManager::getConnection($params)->getWrappedConnection();

$extensionConfigs[] = [
    'dbal' => [
        'connections' => [
            'default' => [
                'server_version' => $connection->getServerVersion(),
            ],
        ],
    ],
];

This will always store the server version so the error message is never shown if the MySQL server goes away. And if the DB connection fails at container build time, the exception will be thrown.

@aschempp
Copy link
Member

aschempp commented Mar 14, 2018 via email

@leofeyer
Copy link
Member

I also agree with @ausi and I also think that this is a Symfony issue. Still we should keep working around it in the Plugin class as we did in the past until the issue has been fixed in Symfony and/or Doctrine.

@leofeyer
Copy link
Member

So how do we proceed here? @aschempp @ausi Do you want to debug why the Symfony exception handler is not triggered in this case and then open a ticket in Symfony's tracker? Otherwise I would commit my changes to our existing workaround mentioned above.

@ausi
Copy link
Member

ausi commented Mar 14, 2018

From symfony/symfony#15581:

it is too early in the process to have the customized error page (which is handled by a controller and so requires a booted kernel).

I’m not sure if it is wrong that Doctrine throws an exception before the kernel is booted. But if it connects to the database that early it is probably correct to do so.

As we seem to all agree that in the prod environment no error message should be shown under any circumstances, I looked up the documentation for PHPs display_errors and it says:

This is a feature to support your development and should never be used on production systems (e.g. systems connected to the internet).

So it seems to be a configuration error that display_errors is turned on on a production webserver. @jommbee can you ask your hosting provider why they don’t follow this recommendation from PHP?

IMO the best solution for us is to add the following line to the top of our app.php (if we want to fix misconfigured webservers):

ini_set('display_errors', 0);

@ausi
Copy link
Member

ausi commented Mar 14, 2018

See also symfony/symfony#22736

@jommbee
Copy link
Author

jommbee commented Mar 15, 2018

Many thanks to everyone for the quick reconnaissance.
It actually behaves as described here. The default setting was on.

I wrote my hoster and pointed out the facts to him.

@leofeyer
Copy link
Member

Thank you for doing the research @ausi. Adding ini_set('display_errors', 0); seems reasonable. We can then remove our workaround entirely.

leofeyer added a commit to contao/manager-bundle that referenced this issue Mar 15, 2018
@leofeyer
Copy link
Member

Fixed in contao/manager-bundle@bebef40.

@leofeyer leofeyer self-assigned this Mar 15, 2018
leofeyer added a commit to contao/manager-bundle that referenced this issue Mar 15, 2018
@leofeyer
Copy link
Member

I will have to revert the changes from contao/manager-bundle@bebef40 as the entry point cannot determine whether Contao is installed on a production or development system.

If I e.g. access Contao through the app.php entry point on my development system, I actually want to see the error messages. Therefore – just like it is now in Symfony 4 – the server should set the environment for the application and we must not make assumptions based on the entry point.

@leofeyer leofeyer reopened this Apr 11, 2018
@leofeyer leofeyer modified the milestones: 4.4.17, 4.4.18 Apr 11, 2018
@leofeyer leofeyer modified the milestones: 4.4.18, 4.4.17 Apr 12, 2018
@fritzmg
Copy link
Contributor

fritzmg commented Apr 12, 2018

If I e.g. access Contao through the app.php entry point on my development system, I actually want to see the error messages.

But why would you choose that entry point to see the error messages?

Though, granted, there are sometimes errors that only happen in prod and not in dev (or the other way around).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants