View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0007286 | OXID eShop (all versions) | 4.07. Source code, Test | public | 2021-11-11 16:37 | 2024-08-07 10:19 |
Reporter | Steven | Assigned To | |||
Priority | low | Severity | minor | Reproducibility | always |
Status | acknowledged | Resolution | open | ||
Product Version | 6.3.1 | ||||
Summary | 0007286: Logger Service's fallback in case of corrupted DI Container uses DI Container again | ||||
Description | First of all: This issue was discovered investigating another possible issue linked to the container_cache.php file. Therefore the issue is described according this exact usecase. However it is not known in which situation this also might happen. The main issue is a fallback, which does not function as a real fallback, since it uses the ContainerFactory again, which actually is the main reason to fail in the first place and obviously leads to start the fallback. In short: If A fails, let's use B...which uses A. If your source/tmp/container_cache.php file exists, but is corrupted (e.g. empty), the OXID framework runs into an error while trying to retrieve a service from the container. The framework correctly wants to write an exception into the logfile by calling OxidEsales\EshopCommunity\Core\Exception\ExceptionHandler::handleUncaughtException To do so, the framework first tries to initialize the LoggerService via the ContainerFactory, which results in an exception again, since the container_cache is still broken. However, this exception is also catched correctly. Then the frameworks wants to initialize the Logger without the DI Container - or at least that's what it states: /** * Its not possible to get the logger from the DI container. * Try again to log original exception (without DI container) in order to show the root cause of a problem. */ try { $loggerServiceFactory = new LoggerServiceFactory(new Context(Registry::getConfig())); $logger = $loggerServiceFactory->getLogger(); $logger->error($this->getFormattedException($exception)); } catch (\Throwable $throwableWithoutPossibilityToWriteToLogFile) { // It is not possible to log because e.g. the log file is not writable. } This time $logger = $loggerServiceFactory->getLogger(); is used, which later tries to establish a database connection via the method OxidEsales\EshopCommunity\Core\Database\Adapter\Doctrine\Database::connect This connect method needs to get the connection configuration, which brings us to the method OxidEsales\EshopCommunity\Core\Database\Adapter\Doctrine\Database::getConnectionConfiguration which then calls OxidEsales\EshopCommunity\Core\Database\Adapter\Doctrine\Database::configureSqlLogger private function configureSqlLogger(Configuration $configuration): void { $container = ContainerFactory::getInstance()->getContainer(); /** logger instantiation requires auto-wiring(compiled container) */ if ($container->isCompiled()) { $databaseLogger = $container->get(DatabaseLoggerFactoryInterface::class)->getDatabaseLogger(); $configuration->setSQLLogger($databaseLogger); } } As you can see, it uses the ContainerFactory on first line and therefore runs into an error the third time. The logger (obviously) can't be initialized with the "fallback" and the exception is not written to the log. | ||||
Steps To Reproduce | - Open the file source/tmp/container_cache.php. - Corrupt the file by emptying it. Do not delete it completely. - Open your shop in your webbrowser. - You will see a maintenance mode, but there is no entry in your logfile. The exception "ProjectServiceContainer not found" was thrown, but not written. You can follow the path like described above with a debugger. | ||||
Tags | Cache, Log, Service | ||||
Theme | Not defined | ||||
Browser | Not defined | ||||
PHP Version | Not defined | ||||
Database Version | Not defined | ||||