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

Enh: Attempt to show better error messages when DB-Connection is invalid #6512

Merged
merged 1 commit into from Aug 17, 2023

Conversation

martin-rueegg
Copy link
Contributor

@martin-rueegg martin-rueegg commented Aug 15, 2023

What kind of change does this PR introduce?

  • Bugfix

Does this PR introduce a breaking change?

  • No

If yes, please describe the impact and migration path for existing applications:

The PR fulfills these requirements:

  • It's submitted to the develop branch, not the master branch if no hotfix
  • All tests are passing
  • New/updated tests are included
  • Changelog was modified

Other information:

When the connection information is wrong, or the database server name resolution fails, there are misleading error messages as there is actually no error handling of that situation so far.

This PR is a poor man's attempt to give the user some sort of helpful information. Yes, it does not look pretty and styled, but that's partly because the theming tries to access the db itself...

Particularly un-informative is the error when you try to run migrations with an invalid connection configuration.

@what-the-diff
Copy link

what-the-diff bot commented Aug 15, 2023

PR Summary

  • Enhancement: Display error messages for invalid DB connection configurations
    Now, when the database connection settings are not configured correctly, clear and informative error messages would be shown. We have achieved this by introducing a method (handleConnectionErrors()) to identify and handle such issues.

  • Feature: Introduction of Application Interface
    With the new Application interface, an onInit event is being fired up when the web application is finished initializing. This helps in better observing and managing the lifecycle of the application.

  • Improvement: Notification link for pending space approval
    Here, pending space approval notifications are linked directly to the management page to further streamline the approval process.

  • Featurization: Initiate the Markdown field type for user account profiles
    This introduces a Markdown field type into user account profiles to improve text formatting options and enhance user interaction.

  • Robustness: Time Zone Update in the Configuration
    The default time zone within the application environment has been updated for better time management and scheduling purposes.

  • Maintenance: Refreshed configuration timestamps
    For better tracking and version control, the config_created_at parameter value has been updated with the current timestamp.

It's worth noting that there are other minor changes in the codebase, mostly updating the usage of humhub\libs\Helpers across different files, modifying comments, and formatting tweaks that mainly enhance the code readability and consistency. These changes, whilst minor, also contribute to the overall maintenance of the project.

Also, it's confirmed that a few files only received timestamp updates or comments/whitespace revisions and one file has not been amended at all.

@martin-rueegg martin-rueegg force-pushed the enh/db-connection-error branch 3 times, most recently from 0a05d3e to 728e13f Compare August 15, 2023 06:32
@martin-rueegg martin-rueegg marked this pull request as ready for review August 15, 2023 07:21
Copy link
Contributor

@luke- luke- left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@martin-rueegg Thanks, looks good for me. If this is not only used on console usage, we need to ensure that no database creds are leaked.

@martin-rueegg
Copy link
Contributor Author

@luke-

@martin-rueegg Thanks, looks good for me. If this is not only used on console usage, we need to ensure that no database creds are leaked.

I see, great point, thank you!

Because the password would be included in the connection string? I guess, we could leave the output of the connection string to the console and otherwise print an error to the log.

Would that do?

@luke-
Copy link
Contributor

luke- commented Aug 16, 2023

@martin-rueegg Currently it is only used in the console context anyway, right? If so, we can merge it.

@martin-rueegg
Copy link
Contributor Author

@luke- nope, it is also shown in web context. But I have entirely removed the DSN in web context. So the only way where the DSN would be shown on the web is while running migrations, as this is run as a console task from the webserver, right?

But a migration is only run by humhub admins? It could still be a problem as the humhub admin and the web server admin aren't necessarily the same people.

Otherwise I completely remove the DSN and write the message to a temp-file and only display the path of that temp file to the user (as it makes no sense sending anything to the log which might try to access the db as well).

I mean it's a rare case where this scenario happens, eg. when moving the installation from one server to another, when changing the DB server or things like that.

@luke-
Copy link
Contributor

luke- commented Aug 16, 2023

@martin-rueegg Ah sorry, I missed the index.php change.

In the web context, I would only output details when the software is running in debug mode. (Currently by default).
https://github.com/humhub/humhub/blob/master/index.php#L9-L11

Otherwise, there should be no detailed output at all in web.


In the migration (web)/console, there is no problem if there are some more detailed information. Maybe we can search and replace the DB dassword with ***?

@martin-rueegg
Copy link
Contributor Author

@luke-

Ah sorry, I missed the index.php change.

In the web context, I would only output details when the software is running in debug mode. (Currently by default). https://github.com/humhub/humhub/blob/master/index.php#L9-L11

Otherwise, there should be no detailed output at all in web.

Actually, the index.php change wasn't there, but it was in the bootstrapping phase when checking the db-connection.
However, currently no detailed output is shown when the web application is running. However, I can re-add it if YII_DEBUG === true and/or YII_ENV === 'dev'

@martin-rueegg
Copy link
Contributor Author

martin-rueegg commented Aug 16, 2023

In the migration (web)/console, there is no problem if there are some more detailed information. Maybe we can search and replace the DB dassword with ***?

@luke- I've did my best: https://regex101.com/r/IRO3rG/2

Console with debug

20:32 $ php7.4 $PHP_XDEBUG ${DEVILBOX_PROJECT_DOCROOT}/protected/yii migrate/up --includeModuleMigrations=1 --interactive=0

Invalid database configuration
==============================

Database not found.

The following connection string was used:
mysql:host=127.0.0.1;dbname=humhub_testx;pwd=****;foo=bar;user=****;


Technical information
---------------------
["yii\\db\\Exception","HY000",1049,"Unknown database 'humhub_testx'"]

PDOException: SQLSTATE[HY000] [1049] Unknown database 'humhub_testx' in /home/mdr/projects/humhub/htdocs/protected/vendor/yiisoft/yii2/db/Connection.php:722
Stack trace:
#0 /home/mdr/projects/humhub/htdocs/protected/vendor/yiisoft/yii2/db/Connection.php(722): PDO->__construct()
#1 /home/mdr/projects/humhub/htdocs/protected/vendor/yiisoft/yii2/db/Connection.php(637): yii\db\Connection->createPdoInstance()
#2 /home/mdr/projects/humhub/htdocs/protected/humhub/commands/MigrateController.php(86): yii\db\Connection->open()
#3 /home/mdr/projects/humhub/htdocs/protected/vendor/yiisoft/yii2/base/Controller.php(176): humhub\commands\MigrateController->beforeAction()
#4 /home/mdr/projects/humhub/htdocs/protected/vendor/yiisoft/yii2/console/Controller.php(180): yii\base\Controller->runAction()
#5 /home/mdr/projects/humhub/htdocs/protected/vendor/yiisoft/yii2/base/Module.php(552): yii\console\Controller->runAction()
#6 /home/mdr/projects/humhub/htdocs/protected/vendor/yiisoft/yii2/console/Application.php(180): yii\base\Module->runAction()
#7 /home/mdr/projects/humhub/htdocs/protected/vendor/yiisoft/yii2/console/Application.php(147): yii\console\Application->runAction()
#8 /home/mdr/projects/humhub/htdocs/protected/vendor/yiisoft/yii2/base/Application.php(384): yii\console\Application->handleRequest()
#9 /home/mdr/projects/humhub/htdocs/protected/yii(32): yii\base\Application->run()
#10 {main}

Console without debug

20:34 $ php7.4 $PHP_XDEBUG ${DEVILBOX_PROJECT_DOCROOT}/protected/yii migrate/up --includeModuleMigrations=1 --interactive=0

Invalid database configuration
==============================

Database not found.

The following connection string was used:
mysql:host=127.0.0.1;dbname=humhub_testx;pwd=****;foo=bar;user=****;


Technical information
---------------------
["yii\\db\\Exception","HY000",1049,"Unknown database 'humhub_testx'"]

web with debug

Invalid database configuration

Database not found.

The following connection string was used:
mysql:host=127.0.0.1;dbname=humhub_testx;pwd=****;foo=bar;user=****;

Technical information

["yii\\db\\Exception","HY000",1049,"Unknown database 'humhub_testx'"]

PDOException: SQLSTATE[HY000] [1049] Unknown database 'humhub_testx' in /shared/httpd/humhub/htdocs/protected/vendor/yiisoft/yii2/db/Connection.php:722
Stack trace:
#0 /shared/httpd/humhub/htdocs/protected/vendor/yiisoft/yii2/db/Connection.php(722): PDO->__construct('mysql:host=127....', 'humhub', 'humhub', NULL)
#1 /shared/httpd/humhub/htdocs/protected/vendor/yiisoft/yii2/db/Connection.php(637): yii\db\Connection->createPdoInstance()
#2 /shared/httpd/humhub/htdocs/protected/vendor/yiisoft/yii2/db/Connection.php(1067): yii\db\Connection->open()
#3 /shared/httpd/humhub/htdocs/protected/vendor/yiisoft/yii2/db/Connection.php(1054): yii\db\Connection->getMasterPdo()
#4 /shared/httpd/humhub/htdocs/protected/vendor/yiisoft/yii2/db/mysql/QueryBuilder.php(413): yii\db\Connection->getSlavePdo(true)
#5 /shared/httpd/humhub/htdocs/protected/vendor/yiisoft/yii2/db/mysql/QueryBuilder.php(437): yii\db\mysql\QueryBuilder->supportsFractionalSeconds()
#6 /shared/httpd/humhub/htdocs/protected/vendor/yiisoft/yii2/db/mysql/QueryBuilder.php(59): yii\db\mysql\QueryBuilder->defaultTimeTypeMap()
#7 /shared/httpd/humhub/htdocs/protected/vendor/yiisoft/yii2/base/BaseObject.php(109): yii\db\mysql\QueryBuilder->init()
#8 /shared/httpd/humhub/htdocs/protected/vendor/yiisoft/yii2/db/QueryBuilder.php(116): yii\base\BaseObject->__construct(Array)
#9 [internal function]: yii\db\QueryBuilder->__construct(Object(yii\db\Connection), Array)
#10 /shared/httpd/humhub/htdocs/protected/vendor/yiisoft/yii2/di/Container.php(411): ReflectionClass->newInstanceArgs(Array)
#11 /shared/httpd/humhub/htdocs/protected/vendor/yiisoft/yii2/di/Container.php(170): yii\di\Container->build('yii\\db\\mysql\\Qu...', Array, Array)
#12 /shared/httpd/humhub/htdocs/protected/vendor/yiisoft/yii2/BaseYii.php(345): yii\di\Container->get('yii\\db\\mysql\\Qu...', Array)
#13 /shared/httpd/humhub/htdocs/protected/vendor/yiisoft/yii2/db/mysql/Schema.php(225): yii\BaseYii::createObject('yii\\db\\mysql\\Qu...', Array)
#14 /shared/httpd/humhub/htdocs/protected/vendor/yiisoft/yii2/db/Schema.php(247): yii\db\mysql\Schema->createQueryBuilder()
#15 /shared/httpd/humhub/htdocs/protected/vendor/yiisoft/yii2/db/Connection.php(884): yii\db\Schema->getQueryBuilder()
#16 /shared/httpd/humhub/htdocs/protected/vendor/yiisoft/yii2/db/Query.php(157): yii\db\Connection->getQueryBuilder()
#17 /shared/httpd/humhub/htdocs/protected/vendor/yiisoft/yii2/db/Query.php(304): yii\db\Query->createCommand(Object(yii\db\Connection))
#18 /shared/httpd/humhub/htdocs/protected/vendor/yiisoft/yii2/web/DbSession.php(185): yii\db\Query->scalar(Object(yii\db\Connection))
#19 [internal function]: yii\web\DbSession->readSession('3fbe391c5e2a686...')
#20 /shared/httpd/humhub/htdocs/protected/vendor/yiisoft/yii2/web/Session.php(149): session_start()
#21 /shared/httpd/humhub/htdocs/protected/vendor/yiisoft/yii2/web/Session.php(699): yii\web\Session->open()
#22 /shared/httpd/humhub/htdocs/protected/vendor/yiisoft/yii2/web/User.php(691): yii\web\Session->get('__id')
#23 /shared/httpd/humhub/htdocs/protected/vendor/yiisoft/yii2/web/User.php(199): yii\web\User->renewAuthStatus()
#24 /shared/httpd/humhub/htdocs/protected/vendor/yiisoft/yii2/web/User.php(367): yii\web\User->getIdentity()
#25 /shared/httpd/humhub/htdocs/protected/vendor/yiisoft/yii2/base/Component.php(139): yii\web\User->getIsGuest()
#26 /shared/httpd/humhub/htdocs/protected/humhub/components/i18n/I18N.php(53): yii\base\Component->__get('isGuest')
#27 /shared/httpd/humhub/htdocs/protected/humhub/components/bootstrap/LanguageSelector.php(29): humhub\components\i18n\I18N->autosetLocale()
#28 /shared/httpd/humhub/htdocs/protected/vendor/yiisoft/yii2/base/Application.php(325): humhub\components\bootstrap\LanguageSelector->bootstrap(Object(humhub\components\Application))
#29 /shared/httpd/humhub/htdocs/protected/vendor/yiisoft/yii2/web/Application.php(69): yii\base\Application->bootstrap()
#30 /shared/httpd/humhub/htdocs/protected/humhub/components/Application.php(84): yii\web\Application->bootstrap()
#31 /shared/httpd/humhub/htdocs/protected/vendor/yiisoft/yii2/base/Application.php(271): humhub\components\Application->bootstrap()
#32 /shared/httpd/humhub/htdocs/protected/humhub/components/Application.php(65): yii\base\Application->init()
#33 /shared/httpd/humhub/htdocs/protected/vendor/yiisoft/yii2/base/BaseObject.php(109): humhub\components\Application->init()
#34 /shared/httpd/humhub/htdocs/protected/vendor/yiisoft/yii2/base/Application.php(204): yii\base
\BaseObject->__construct(Array)
#35 /shared/httpd/humhub/htdocs/protected/humhub/components/Application.php(49): yii\base\Application->__construct(Array)
#36 /shared/httpd/humhub/htdocs/index.php(28): humhub\components\Application->__construct(Array)
#37 {main}

Web without debug

Invalid database configuration

Database not found.

@martin-rueegg martin-rueegg force-pushed the enh/db-connection-error branch 2 times, most recently from 578211a to cbeaf7d Compare August 16, 2023 18:50
Copy link
Contributor

@luke- luke- left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@martin-rueegg Looks very good. Thank you!

I've been thinking about introducing a humhub\helpers namespace for a while and this could be worth to be added into DatabaseHelper or ErrorHelper there for example.

Should we do this with this PR?

I can also do this afterwards...

@martin-rueegg
Copy link
Contributor Author

In my point of view, humhub\lib and humhub\helpers are kinda same, same but different ... :-)

However, I'm happy start the thing. I would, however, not touch any other of the lib\*Helper classes. For two reasons:

  • I'd urge to move the current files/classes to the new namespace, commit that, than create a new class at the old place extending from the new one. This for backwards-compatibility. However, if that is done in a separate commit, then the move of the class is recoreded in git. If the move and the re-creation of the old are in the same commit, then the tracking is lost.
  • Also, moving those classes will affect tons of files (billions and billions ;-) ) and therefore should not be in this one PR for reasons of oversight.

If we create a humhub\helpers\DatabaseHelper class, I'd suggest to not only put the error handling there, but also the isDatabaseInstalled() method from the BasicSettingsManager which is currently abused.

It could also make sense to have the isDatabaseInstalled() (and potentially isDatabaseAvailable()) in DatabaseHelper, while the actual handling of the error in ErrorHelper ...

How do you want it to be or shall I make a suggestion along these lines?

@luke-
Copy link
Contributor

luke- commented Aug 17, 2023

@martin-rueegg

However, I'm happy start the thing. I would, however, not touch any other of the lib\*Helper classes. For two reasons:

  • I'd urge to move the current files/classes to the new namespace, commit that, than create a new class at the old place extending from the new one. This for backwards-compatibility. However, if that is done in a separate commit, then the move of the class is recoreded in git. If the move and the re-creation of the old are in the same commit, then the tracking is lost.

Good point + also the hint regarding the GIT tracking.

  • Also, moving those classes will affect tons of files (billions and billions ;-) ) and therefore should not be in this one PR for reasons of oversight.

Migration from humhub\libs to humhub\helpers should be done gradually. This is not meant to be a point for now. This PR should only be the first file in the helpers namespace.

If we create a humhub\helpers\DatabaseHelper class, I'd suggest to not only put the error handling there, but also the isDatabaseInstalled() method from the BasicSettingsManager which is currently abused.
It could also make sense to have the isDatabaseInstalled() (and potentially isDatabaseAvailable()) in DatabaseHelper, while the actual handling of the error in ErrorHelper ...

I would prefer: we finish this PR. One more change should be to move the new helper method to its own file in the humhub\helpers namespace.

Further improvements e.g. the suggested isDatabaseInstalled() can be then done in a seperate PR. But I like the idea.

@martin-rueegg martin-rueegg changed the base branch from develop to next August 17, 2023 16:26
@martin-rueegg
Copy link
Contributor Author

@luke- like so?

protected/yii Show resolved Hide resolved
@luke- luke- merged commit c7e2f45 into humhub:next Aug 17, 2023
6 checks passed
@martin-rueegg martin-rueegg deleted the enh/db-connection-error branch August 17, 2023 17:55
@martin-rueegg
Copy link
Contributor Author

martin-rueegg commented Aug 18, 2023

@luke-

  • I'd urge to move the current files/classes to the new namespace, commit that, than create a new class at the old place extending from the new one. This for backwards-compatibility. However, if that is done in a separate commit, then the move of the class is recorded in git. If the move and the re-creation of the old are in the same commit, then the tracking is lost.

Good point + also the hint regarding the GIT tracking.

Yes, it is a underestimated or unknown limitation of GIT, that it does not track actual file moves. All it does, when committing (at the end, be it a squashed commit) see, if any newly created file resembles any deleted file. That means, that if you move a file and change it at the same time too much, GIT will commit a delete and create, rather than a move. An example of this is the move of protected/humhub/config/__autocomplete.php here, which was previously protected/humhub/Yii.php but the tracking broke in that (squashed) commit.

Hence, best thing is:

  1. git mv file
  2. git commit with message
  3. edit file
  4. potentially add new file at the old location (e.g. class for backwards-compatibility extending the class at the new location)
  5. git commit with message
  6. And do NOT squash these commits later! :-)

@luke-
Copy link
Contributor

luke- commented Aug 18, 2023

@martin-rueegg Especially point 6 is important, because I usually always squash merge PRs. :-)

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

Successfully merging this pull request may close these issues.

None yet

2 participants