3

Working on a symfony application that uses nusoap (is this the best method for integrating soap work with php/symfony?) for taking credit card payments.

I've simplified an example of my code below.

What I'm struggling with is the best way to handle exceptions. The example below only has 1 custom exception (where should my custom exceptions reside within the directory structure of symfony? (lib/exception?)) But what happens when there are several different types of exceptions that handle a specific error? It's not very elegant to have a try/catch block with 20 odd exceptions.

I'm also not sure of where I should be throwing and catching. I need to set some user flashes to alert the user of any problems, so I figure the catching should be done in the actions controller rather than within the class that handles the soap call.

Could anyone please advise where I might be going wrong?

I hate messy code/solutions and want to stick to the DRY principle as much as possible. I think I might also be missing some built in symfony functionality that might help with this but whenever I search I usually find examples that are for symfony 1.2, I'm using 1.4.

Some examples would be great, thanks.

lib/soap_payment.class.php

class SoapPayment
{
  public function charge()
  {
    /*assume options are setup correctly for sake of example*/
    try
    {
      $this->call();
    }
    catch (SoapPaymentClientFaultException $e)
    {
      /* should this be caught here? */
    }
  }

  private function call()
  {
    $this->client->call($this->options);

    if ($this->client->hasFault())
    {
      throw new SoapPaymentClientFaultException();
    }
  }
}

apps/frontend/payment/actions/actions.class.php

class paymentActions extends sfActions
{
   public function executeCreate(sfWebRequest $request)
   {
     /* check form is valid etc */

     $soap_payment = new SoapPayment();

     try
     {
       $soap_payment->charge();
     }
     catch (SoapPaymentClientFaultException $e)
     {
       /* or throw/catch here? */
       $this->getUser()->setFlash('error', ...);

       $this->getLogger()->err(...);
     }   

     /* save form regardless, will set a flag to check if successful or not in try/catch block */
   }
}

1 Answer 1

3

One not very well known feature of Symfony is that exceptions can manage the content sent in a response. So you could do something like this:

class SoapException extends sfException
{
  public function printStackTrace() //called by sfFrontWebController when an sfException is thrown
  {
    $response = sfContext::getInstance()->getResponse();
    if (null === $response)
    {
      $response = new sfWebResponse(sfContext::getInstance()->getEventDispatcher());
      sfContext::getInstance()->setResponse($response);
    }

    $response->setStatusCode(5xx);
    $response->setContent('oh noes'); //probably you want a whole template here that prints the message that was a part of the SoapException
  }
}

If you need a cleaner handling of SOAP exceptions, like setting flashes, etc. you'll probably have to catch each exception. One idea here might be to create a generic SoapException class that is extended by more specific SoapExceptions so you don't have to catch a bunch of different types. The above code may be a useful fallback mechanism as well.

Finally, yes, you should place custom exceptions in lib/exception.

Sign up to request clarification or add additional context in comments.

2 Comments

I don't see a lib/exception directory. However, I do see a lib/vendor/symfony/lib/exception directory; is this the directory you mean?
@rlandster Just make a lib/exception directory. lib/vendor/ is for 3rd party libraries and shouldn't be modified.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.