Search code examples
phpsymfonysymfony3

How to use Container to access parameters on a custom Exception


I have been struggling a bit to understand how can I make use of the Container that gives me access to the parameters located at config/parameters.yml.

The problem in my hands is I created some custom Exceptions and I created a library that slacks me every time one of those exceptions is triggered. For that, I need to send the container to the Logger in order to be able to pull those through within the library.

But I am failing to be able to grab a hold on the container. I have an idea it needs to be injected and that I could achieve such in the config/services.yml but I am failing to understand how.

So far this is what I have come to achieve:

My Custom Exception Parent

Because all exceptions extend from the parent, they will all trigger the Logger. And it is at this point I need the container to exist:

abstract class CriticalLogAlertException extends \RuntimeException
{
    protected $logger;

    public function __construct ($message = "", $code = 0, Throwable $previous = NULL)
    {
        parent::__construct($message, $code, $previous);

        Log::critical(
                      $this->message, 
                      [], 
                      AbstractCredentialsFactory::YAML_TYPE,
                     'PARAMETERS CONTAINER ACCESS NEEDS TO BE ADDED HERE'
                    );
    }

    abstract public function generateMessage($message) : string;
}

What I though was on creating on this class a method setContainer() that I could use in my config/services.yml:

public function setContainer(ContainerInterface $container)
{
    $this->container - $container;
}

So at this point I could create a property in the abstract class and use that to pass it to the library as it would be already available at class execution. Though I am not too certain this is achievable or correct;

My config/services.yml

Below is the code I added to my services container:

 ExceptionContainer:
      class: AppBundle\Exception\CriticalLogAlertException
      calls:
          - [ setContainer,[ @service_container ] ]

Could someone help me understanding if it something I am missing or misunderstanding in order to set it available?

NOTE: If there is anything else required to better understand my problem, please let me know so I can update my question :)

Thank you in advance!


Solution

  • Sooo, this took me a while but I had to dive deeper in order to understand, which meant to go through some fights and research before being able to start understanding it a bit better.

    Was left for a while even though I got it working a while back, but for those wondering the same and new to the process let me share a bit :)

    Because I was instantiating the exceptions with throw new meant I had direct access to the __construct method. This meant, if my exception was expecting a ContainerInterface I had to provide one.

    Now, two case scenarious could work with this.

    1. Injection

    With Injection I can autowire the requirements either by using an available service (which we can check with below command);

    php bin/console debug:autowiring
    

    Or, if injecting a custom class, I needed to specify where, which and what it provides at services.yml

    An possible example of what I am refering to add to services.yml can be seen below:

    TestException:
            class: AppBundle\Exception\TerminationAmlkyc
            arguments: ['@service_container']
            public: true
    

    2. Instantiation

    In my case, I either transferred the ContainerInterface whenever I needed it for a new class or was able to Instanciated as I referenced above.

    Because my origin was through a ContainerAwareCommand I could make use of $this->getContainer() to retrieve it and then pass it to the exceptions whenever needed.

    throw new TestException($this->getContainer())