91 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			91 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| namespace nulib;
 | |
| 
 | |
| use RuntimeException;
 | |
| use Throwable;
 | |
| 
 | |
| /**
 | |
|  * Class UserException: une exception qui peut en plus contenir un message
 | |
|  * utilisateur
 | |
|  */
 | |
| class UserException extends RuntimeException {
 | |
|   /** @param Throwable|ExceptionShadow $e */
 | |
|   static function get_user_message($e): ?string {
 | |
|     if ($e instanceof self) return $e->getUserMessage();
 | |
|     else return null;
 | |
|   }
 | |
| 
 | |
|   /** @param Throwable|ExceptionShadow $e */
 | |
|   static final function get_user_summary($e): string {
 | |
|     $parts = [];
 | |
|     $first = true;
 | |
|     while ($e !== null) {
 | |
|       $message = self::get_user_message($e);
 | |
|       if (!$message) $message = "(no message)";
 | |
|       if ($first) $first = false;
 | |
|       else $parts[] = "caused by ";
 | |
|       $parts[] = get_class($e) . ": " . $message;
 | |
|       $e = $e->getPrevious();
 | |
|     }
 | |
|     return implode(", ", $parts);
 | |
|   }
 | |
| 
 | |
|   /** @param Throwable|ExceptionShadow $e */
 | |
|   static function get_message($e): ?string {
 | |
|     $message = $e->getMessage();
 | |
|     if (!$message && $e instanceof self) $message = $e->getUserMessage();
 | |
|     return $message;
 | |
|   }
 | |
| 
 | |
|   /** @param Throwable|ExceptionShadow $e */
 | |
|   static final function get_summary($e): string {
 | |
|     $parts = [];
 | |
|     $first = true;
 | |
|     while ($e !== null) {
 | |
|       $message = self::get_message($e);
 | |
|       if (!$message) $message = "(no message)";
 | |
|       if ($first) $first = false;
 | |
|       else $parts[] = "caused by ";
 | |
|       if ($e instanceof ExceptionShadow) $class = $e->getClass();
 | |
|       else $class = get_class($e);
 | |
|       $parts[] = "$class: $message";
 | |
|       $e = $e->getPrevious();
 | |
|     }
 | |
|     return implode(", ", $parts);
 | |
|   }
 | |
| 
 | |
|   /** @param Throwable|ExceptionShadow $e */
 | |
|   static final function get_traceback($e): string {
 | |
|     $tbs = [];
 | |
|     $previous = false;
 | |
|     while ($e !== null) {
 | |
|       if (!$previous) {
 | |
|         $efile = $e->getFile();
 | |
|         $eline = $e->getLine();
 | |
|         $tbs[] = "at $efile($eline)";
 | |
|       } else {
 | |
|         $tbs[] = "~~ caused by: " . self::get_summary($e);
 | |
|       }
 | |
|       $tbs[] = $e->getTraceAsString();
 | |
|       $e = $e->getPrevious();
 | |
|       $previous = true;
 | |
|       #XXX il faudrait ne pas réinclure les lignes communes aux exceptions qui
 | |
|       # ont déjà été affichées
 | |
|     }
 | |
|     return implode("\n", $tbs);
 | |
|   }
 | |
| 
 | |
|   function __construct($userMessage, $techMessage=null, $code=0, ?Throwable $previous=null) {
 | |
|     $this->userMessage = $userMessage;
 | |
|     if ($techMessage === null) $techMessage = $userMessage;
 | |
|     parent::__construct($techMessage, $code, $previous);
 | |
|   }
 | |
| 
 | |
|   /** @var ?string */
 | |
|   protected $userMessage;
 | |
| 
 | |
|   function getUserMessage(): ?string {
 | |
|     return $this->userMessage;
 | |
|   }
 | |
| }
 |