Why I've Started Catching DI Exceptions For Code I Know Exists

I’ve recently been moving our SaaS off it’s CI 3 code base. I’ll write a longer post about the whole experience one of these days. Needless to say it’s been filled with it’s share of challenges.

One of those challenges hit me recently.

I’ve been writing new code to use Dependency Injection; something I sorely miss on the occasions I need to dive back into the CI3 code. I’ve also been progressively moving from my own home grown event management code to use Laminas EventManager Interface.

To help with using Laminas EventManager across both the CI3 code base and new code, I have the event registration setup in config files inside each module. These are loaded during the bootstrapping process (in both our new and old code base) using a glob to find all the relevant files in all the config directories for all the sub-modules.

$events = new \Laminas\EventManager\EventManager();
$container = $this->getContainer();
$files = glob(__DIR__ . "/../../../app/Modules/**/Config/Events.php");
// loop through the modules and load up the events.
foreach ($files as $file) {
    include $file;
}

Then in each of the config files the container is used to create the event listener and inject any needed dependencies into it.

$events->attach("registration.created",[$container->get(\App\Modules\Workshops\Events\EmailBusinessRegistrationCreatedEvent::class),"action"]);

So far so good. Nothing really untoward there and nothing that I thought could cause problems.

Everything worked perfectly in production and staging. I was ready to deploy.

I use Envoyer for deployments. It’s a great tool, I couldn’t live without it. If you haven’t used Envoyer, it’s a code deployment tool that goes through a number of steps to deploy your php code. Firstly it will ssh into the server, then it will do a git pull, composer install, symlink some directories and then an php-fpm restart. Sometimes though (maybe it’s Friday afternoon in Envoyer land) it just goes slow. Normally each step will take a couple of seconds (a bit longer for the composer install obviously), but sometimes a step (like changing symlinks or restarting fpm) can take a couple of minutes to complete.

Unfortunately, today was the day for slow motion mode! My new code was deployed, the symlinks were recreated, and suddenly the logs exploded with errors. php-fpm hadn’t restarted yet and the container was unable to find the new classes for the newly introduced event manager listeners. It was 2 minutes (143 seconds exactly) of frustratingly watching the progress bar!

A simple problem, that could easily have been avoided using a try-catch block. A good reason that exceptions should always be caught, even when you don’t think you need to.