I am working on a PHP project where I am catching exceptions and logging the errors using Monolog and returning a user-friendly page as a response.
The project is currently in its baby phases, so I am just logging the errors to a file using Monolog's StreamHandler class in an app directory outside of the public's reach, as I progress I realize this may fail if there's an IO error of some sort and so I will also be logging to a database (possible ElasticSearch) and sending critical errors via email to the admin.
As I am using the StreamHandler, I can see that it throws an exception if it fails to open the file.
Now, how should I be handling this case of exception and how should I log it if the logging mechanism itself fails?
I can have the exception be handled by another logger which sends an email on such critical situations, but again, how do I handle the exception being thrown by the mailer?
I assume the page would be filled with too many try-catch blocks with loggers spread out throughout the page which would look downright ugly.
Is there an elegant, clean solution that doesn't involve too many nested try-catch blocks that are being used in large scale projects? (Unpopular opinions are also welcome)
Here is some code for reference:
try
{
    $routes = require_once(__DIR__.'/Routes.php');
    $router = new RouteFactory($routes, $request, \Skletter\View\ErrorPages::class);
    $router->buildPaths('Skletter\Controller\\', 'Skletter\View\\');
    $app = new Application($injector);
    $app->run($request, $router);
}
catch (InjectionException | InvalidErrorPage | NoHandlerSpecifiedException $e)
{
    $log = new Logger('Resolution');
    try
    {
        $log->pushHandler(new StreamHandler(__DIR__ . '/../app/logs/error.log', Logger::CRITICAL));
        $log->addCritical($e->getMessage(),
            array(
                'Stack Trace' => $e->getTraceAsString()
            ));
    }
    catch (Exception $e)
    {
        echo "No access to log file: ". $e->getMessage();
        // Should I handle this exception by pushing to db or emailing?
        // Can possibly introduce another nested try-catch block 
    }
    finally
    {
        /**
         * @var \Skletter\View\ErrorPageView $errorPage
         */
        $errorPage = $injector->make(\Skletter\View\ErrorPages::class);
        $errorPage->internalError($request)->send();
    }
}
 
     
     
     
     
    