Exception.php 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. <?php
  2. namespace ModulesGarden\ProxmoxAddon\Core\HandlerError\Exceptions;
  3. use ModulesGarden\ProxmoxAddon\Core\ServiceLocator;
  4. use ModulesGarden\ProxmoxAddon\Core\HandlerError\ErrorManager;
  5. use \ModulesGarden\ProxmoxAddon\Core\HandlerError\ErrorCodes\ErrorCodesLib;
  6. /**
  7. * Base module Exception type
  8. *
  9. * @author Sławomir Miśkowicz <rafal.os@modulesgarden.com>
  10. */
  11. class Exception extends \Exception
  12. {
  13. use \ModulesGarden\ProxmoxAddon\Core\Traits\ErrorCodesLibrary;
  14. use \ModulesGarden\ProxmoxAddon\Core\Traits\Lang;
  15. use \ModulesGarden\ProxmoxAddon\Core\Traits\IsDebugOn;
  16. use \ModulesGarden\ProxmoxAddon\Core\UI\Traits\RequestObjectHandler;
  17. /**
  18. * A default error code number, selected when no code number provided
  19. */
  20. const DEFAULT_ERROR_CODE = 'CORE_ERR_000001';
  21. /**
  22. * An error code object
  23. *
  24. * @var type \ModulesGarden\ProxmoxAddon\Core\HandlerError\ErrorCodes\ErrorCode
  25. */
  26. protected $errorCode = null;
  27. /**
  28. * Every Exception which can be caught as \Exception
  29. * @var type \Exception
  30. */
  31. protected $originalException = null;
  32. /**
  33. * An array of additionall data that will be logged with the Exception in order to help debug
  34. * @var type array
  35. */
  36. protected $additionalData = [];
  37. /**
  38. * An array of strings to be replaced in translate process, eg. for message:
  39. * "An error :xyz: occured" in order to replace key ':xyz:' with a '123' set this
  40. * param to: ['xyz' => '123']
  41. *
  42. * @var type array
  43. */
  44. protected $toTranslate = [];
  45. /**
  46. * This is a way to replace standard ErrorCode message, use it when no original exception
  47. * is present and the ErrorCode message, needs to be replaced, eg. API string error responses
  48. *
  49. * @var type string
  50. */
  51. protected $customMessage = null;
  52. public function __construct($errorCode = null, $additionalData = null, $toTranslate = null, $originalException = null)
  53. {
  54. $this->errorCode = $this->genErrorCode(($errorCode ?: self::DEFAULT_ERROR_CODE));
  55. $this->setAdditionalData($additionalData);
  56. $this->setToTranslate($toTranslate);
  57. $this->setOriginalException($originalException);
  58. }
  59. /**
  60. * Returns an error code for the exception
  61. * @return type string
  62. */
  63. public function getMgCode()
  64. {
  65. return $this->errorCode->getCode();
  66. }
  67. /**
  68. * Returns an error token for the exception, an unique string based on exception occurence timestamp
  69. * @return type string
  70. */
  71. public function getMgToken()
  72. {
  73. return $this->errorCode->getToken();
  74. }
  75. /**
  76. * Returns a date for the exception occurence
  77. * @return type string
  78. */
  79. public function getMgTime()
  80. {
  81. return date("Y-m-d H:i:s", time());
  82. }
  83. /**
  84. * Returns a translated or raw error message
  85. * @param type bool $translate
  86. * @return type string
  87. */
  88. public function getMgMessage($translate = true)
  89. {
  90. if ($translate && !$this->isDebugOn())
  91. {
  92. $this->loadLang();
  93. $message = $this->lang->absoluteTranslate(
  94. $this->errorCode === self::DEFAULT_ERROR_CODE ? 'errorMessage' : 'errorCodeMessage', $this->selectProperMessage());
  95. }
  96. else
  97. {
  98. $message = $this->selectProperMessage();
  99. }
  100. return $this->replaceMessageVars($message);
  101. }
  102. /**
  103. * Replaces provided vars in the message string
  104. *
  105. * @param type $message string
  106. */
  107. public function replaceMessageVars($message)
  108. {
  109. foreach ($this->toTranslate as $key => $value)
  110. {
  111. $message = str_replace(':' . $key . ':', $value, $message);
  112. }
  113. return $message;
  114. }
  115. /**
  116. * Returns an originall exception object if such was provided
  117. *
  118. * @return type \Exception
  119. */
  120. public function getOriginalException()
  121. {
  122. return $this->originalException;
  123. }
  124. /**
  125. * Returns an array of data to be displayed when exception occured
  126. *
  127. * @return type array
  128. */
  129. public function getDetailsToDisplay()
  130. {
  131. $errorDetails = [];
  132. if ($this->isDebugOn() && $this->isAdminLogedIn())
  133. {
  134. $errorDetails['errorCode'] = $this->getMgCode();
  135. $errorDetails['errorToken'] = $this->getMgToken();
  136. $errorDetails['errorTime'] = $this->getMgTime();
  137. }
  138. $errorDetails['errorMessage'] = $this->getMgMessage(true);
  139. return $errorDetails;
  140. }
  141. /**
  142. * Returns an array of data to be logged when exception occured
  143. *
  144. * @return type array
  145. */
  146. public function getDetailsToLog()
  147. {
  148. $errorDetails = [];
  149. $errorDetails['errorCode'] = $this->getMgCode();
  150. $errorDetails['errorToken'] = $this->getMgToken();
  151. $errorDetails['errorTime'] = $this->getMgTime();
  152. $errorDetails['errorMessage'] = $this->getMgMessage(false);
  153. $errorDetails['additionalData'] = $this->getAdditionalData();
  154. return $errorDetails;
  155. }
  156. /**
  157. * Select a proper message for the exepction
  158. * Priority:
  159. * 1 custom message
  160. * 2 original Exception message
  161. * 3 error code message
  162. *
  163. * @return type string
  164. */
  165. protected function selectProperMessage()
  166. {
  167. if (is_string($this->customMessage))
  168. {
  169. return $this->customMessage;
  170. }
  171. if ($this->originalException !== null)
  172. {
  173. return $this->originalException->getMessage();
  174. }
  175. return $this->errorCode->getMessage();
  176. }
  177. /**
  178. * Sets a $originalException param, so you can wrap other exception in this one,
  179. * in order to log and parse them automatically
  180. *
  181. * @param \Exception $originalException
  182. */
  183. public function setOriginalException($originalException)
  184. {
  185. if ($originalException instanceof \Exception)
  186. {
  187. $this->originalException = $originalException;
  188. parent::__construct($originalException->getMessage(), $originalException->getCode(), $originalException->getPrevious());
  189. }
  190. }
  191. /**
  192. *
  193. * @param type $data array
  194. * @return $this
  195. */
  196. public function setAdditionalData($data = [])
  197. {
  198. if (is_array($data))
  199. {
  200. $this->additionalData = $data;
  201. }
  202. return $this;
  203. }
  204. /**
  205. *
  206. * @return type array
  207. */
  208. public function getAdditionalData()
  209. {
  210. return $this->additionalData;
  211. }
  212. /**
  213. *
  214. * @param type $data array
  215. * @return $this
  216. */
  217. public function setToTranslate($data = [])
  218. {
  219. if (is_array($data))
  220. {
  221. $this->toTranslate = $data;
  222. }
  223. return $this;
  224. }
  225. /**
  226. *
  227. * @param type $message string
  228. * @return $this
  229. */
  230. public function setCustomMessage($message = null)
  231. {
  232. if (is_string($message) && $message !== '')
  233. {
  234. $this->customMessage = $message;
  235. $this->message = $message;
  236. }
  237. return $this;
  238. }
  239. /**
  240. * Check if the exception should be logged or not
  241. *
  242. * @return boolean
  243. */
  244. public function isLogable()
  245. {
  246. if ($this->errorCode->isLogable())
  247. {
  248. return true;
  249. }
  250. if ($this->isAdminLogedIn() && $this->isDebugOn())
  251. {
  252. return true;
  253. }
  254. return false;
  255. }
  256. /**
  257. * Check if the administrator user is logged in current session
  258. *
  259. * @return boolean
  260. */
  261. public function isAdminLogedIn()
  262. {
  263. $this->loadRequestObj();
  264. $adminId = $this->request->getSession('adminid');
  265. if (is_int($adminId) && $adminId > 0)
  266. {
  267. return true;
  268. }
  269. return false;
  270. }
  271. }