Home > Blockchain >  Custom formatting of PHP exception with collected data
Custom formatting of PHP exception with collected data

Time:12-09

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?

CodePudding user response:

I've done something like this before. I don't recommend trying to force getMessage() to do something different. I recommend implementing a getCustomMessage() on your class instead. However, sometimes we just need to do what we need to do. So...

Because the getMessage() function is final in the Exception class, in order to accomplish what you are doing you will have to write your own Base Exception Class. You will not be able to extend Exception in any meaningful way to accomplish what you want in a single shot.

In other words write a new class that is a reflection of PHP's Exception class. As below

class MySuperAwesomeException implements Throwable {

  // Re-implement all of existing Exception properties
  /* Properties */
  protected string $message = "";
  private string $string = "";
  protected int $code;
  protected string $file = "";
  protected int $line;
  private array $trace = [];
  private ?Throwable $previous = null;



  //This is where you can write your getMessage()
  final public getMessage(): string



  // Re-write all of existing Exception methods or alter any as you see fit.
  /* Methods */
  public __construct(string $message = "", int $code = 0, ?Throwable $previous = null)
  final public getPrevious(): ?Throwable
  final public getCode(): int
  final public getFile(): string
  final public getLine(): int
  final public getTrace(): array
  final public getTraceAsString(): string
  public __toString(): string
  private __clone(): void
}

For Reference: https://www.php.net/manual/en/class.exception.php

CodePudding user response:

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?

  • Related