What is the correct way to gracefully fail Symfony service factory?

666 Views Asked by At

Symfony's documentation for service factories explains how to allow the service container to instantiate services using factories, but does not explain what the recommended best practice is when creation fails, i.e. when the service is not available for whatever reason.

For example; imagine a Redis memory caching service. Inside the factory class, you have a method that will instantiate and return a Redis client object;

public function createRedisClient() {
  $redis = new \Redis();
  $connectionResult = $redis->connect($host, $port);

  return $redis;
}

If the Redis server is temporarily not available, and I would like to be able to gracefully fall back to another solution for storing whatever data we have, should the factory return null, throw an exception of some specific kind, or simply not care about availability?

2

There are 2 best solutions below

0
On BEST ANSWER

If you want a "fallback" solution best practice here is to group those kind of services under a common interface, than try to instantiate one at a time like a "chain of responsibility": first that can be instantiated, returns. Of course in your clients you'll use the interface so this process will be completely straightforward for "client developer".

Best way to obtain this is to have something like SessionStorageFactory (so a generic one) where you can "register" all concrete factories (RedisFactory, ... , DefaultSessionStorageFactory) and try to instantiate one at a time.

Of course the drawback is that if you could need a "superset" of attribute (like host, port and so on) that are useless for all factories but the concrete one where the parameter is required.

1
On

You can use PHP's is_object method :

    public function createRedisClient() {
      $redis = new \Redis();
      $connectionResult = $redis->connect($host, $port);
      if (!is_object($redis)) {
        return false;
      }
      return $redis;
}

Return Value :

Returns TRUE if var is an object, FALSE otherwise.

Reference : PHP is_object