skip to Main Content

I have regular use cases of PHP Exception sub classes where I want to collect up data and then bundle it into a final error message. For example:

  1. checking some data has contiguous days

     $missing = new MissingAdjustmentDataException('');        
    
     $testDate = $period->getPreviousPeriod()->getEnd();
    
     $z = 0;
     while ($testDate <= $period->getEnd() && $z < 500){
         if (!in_array($testDate, array_column($activationRedemptionAdjustmentDays, 'effective') )){
             $missing->addMissingRedemptionAdjustment($testDate);
         }
         if (!in_array($testDate, array_column($platformAdjustmentDays, 'effective') )){
             $missing->addMissingPlatformAdjustment($testDate);
         }
         $testDate->add(new DateInterval('P1D'));
         $z++;
     }
    
  1. Then in my exception, I’m collecting the data in arrays:

     class MissingAdjustmentDataException extends Exception
     {
         private $missingRedemptionAdjustment = [];
    
         private $missingPlatformAdjustment = [];
    
         public function updateMessage()
         {
             $message = 'Missing Adjustment data: ';
             if ($this->missingRedemptionAdjustment){
                 $ra = [];
                 foreach ($this->missingRedemptionAdjustment as $item){
                     $ra[] = $item->format('Y-m-d');
                 }
                 $message .= 'RedemptionAdjustment: '.implode(',',$ra);
             }
             if ($this->missingPlatformAdjustment){
                 $pl = [];
                 foreach ($this->missingRedemptionAdjustment as $item){
                     $pl[] = $item->format('Y-m-d');
                 }
                 $message .= 'PlatformAdjustment: '.implode(',',$pl);
             }
             $this->message = $message;
         }
    
         public function inError() : bool
         {
             if ($this->missingRedemptionAdjustment || $this->missingPlatformAdjustment){
                 return true;
             }else{
                 return false;
             }
         }
    
         public function addMissingRedemptionAdjustment(DateTime $dateTime){
             $this->missingRedemptionAdjustment[] = clone $dateTime;
             $this->updateMessage();
         }
    
         public function addMissingPlatformAdjustment(DateTime $dateTime){
             $this->missingPlatformAdjustment[] = clone $dateTime;
             $this->updateMessage();
         }
     }
    

My main problem is that I cannot find a way to do the formatting of the message in a "lazy" way when $missing->getMessage() is called. It seems to have update $this->message inside the Exception every time I add a data point to the exception.

Is there a better way to do this?

2

Answers


  1. You can execute updateMessage() while catching the exception

    catch(MissingAdjustmentDataException $e) {
        $e->updateMessage();
        echo $e->getMessage();
    }
    

    You will find some advices and hacks in How to change exception message of Exception object?

    Login or Signup to reply.
  2. The issue is that you are mixing two different things: the object that keeps track of the errors, and the exception.
    You should properly seperate them. For example:

    class MissingDataCollector
    {
        private $missingRedemptionAdjustment = [];
        private $missingPlatformAdjustment = [];
    
        public function addMissingRedemptionAdjustment(DateTime $dateTime)
        {
            $this->missingRedemptionAdjustment[] = clone $dateTime;
        }
    
        public function addMissingPlatformAdjustment(DateTime $dateTime)
        {
            $this->missingPlatformAdjustment[] = clone $dateTime;
        }
    
        public function check()
        {
            if ($this->missingRedemptionAdjustment || $this->missingPlatformAdjustment)
                throw new Exception($this->getMessage());
        }
    
        private function getMessage()
        {
            $message = 'Missing Adjustment data:';
            if ($this->missingRedemptionAdjustment){
                $ra = [];
                foreach ($this->missingRedemptionAdjustment as $item){
                    $ra[] = $item->format('Y-m-d');
                }
                $message .= ' RedemptionAdjustment: '.implode(',', $ra);
            }
            if ($this->missingPlatformAdjustment){
                $pl = [];
                foreach ($this->missingRedemptionAdjustment as $item){
                     $pl[] = $item->format('Y-m-d');
                }
                $message .= ' PlatformAdjustment: '.implode(',', $pl);
            }
            return $message;
        }
    }
    

    And the way to use it:

    $missing = new MissingDataCollector();
    
    // Some processing that may call addMissingRedemptionAdjustment() or addMissingPlatformAdjustment()
    ...
    
    // Throw an exception in case of missing data
    $missing->check();
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search