ErrorHandler.php 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. <?php
  2. /**
  3. * File for ErrorHandler utility class.
  4. * @package Phrity > Util > ErrorHandler
  5. */
  6. namespace Phrity\Util;
  7. use ErrorException;
  8. use Throwable;
  9. /**
  10. * ErrorHandler utility class.
  11. * Allows catching and resolving errors inline.
  12. */
  13. class ErrorHandler
  14. {
  15. /* ----------------- Public methods ---------------------------------------------- */
  16. /**
  17. * Set error handler to run until removed.
  18. * @param mixed $handling
  19. * - If null, handler will throw ErrorException
  20. * - If Throwable $t, throw $t with ErrorException attached as previous
  21. * - If callable, will invoke callback with ErrorException as argument
  22. * @param int $levels Error levels to catch, all errors by default
  23. * @return mixed Previously registered error handler, if any
  24. */
  25. public function set($handling = null, int $levels = E_ALL)
  26. {
  27. return set_error_handler($this->getHandler($handling), $levels);
  28. }
  29. /**
  30. * Remove error handler.
  31. * @return bool True if removed
  32. */
  33. public function restore(): bool
  34. {
  35. return restore_error_handler();
  36. }
  37. /**
  38. * Run code with error handling, breaks on first encountered error.
  39. * @param callable $callback The code to run
  40. * @param mixed $handling
  41. * - If null, handler will throw ErrorException
  42. * - If Throwable $t, throw $t with ErrorException attached as previous
  43. * - If callable, will invoke callback with ErrorException as argument
  44. * @param int $levels Error levels to catch, all errors by default
  45. * @return mixed Return what $callback returns, or what $handling retuns on error
  46. */
  47. public function with(callable $callback, $handling = null, int $levels = E_ALL)
  48. {
  49. $error = null;
  50. $result = null;
  51. try {
  52. $this->set(null, $levels);
  53. $result = $callback();
  54. } catch (ErrorException $e) {
  55. $error = $this->handle($handling, $e);
  56. } finally {
  57. $this->restore();
  58. }
  59. return $error ?? $result;
  60. }
  61. /**
  62. * Run code with error handling, comletes code before handling errors
  63. * @param callable $callback The code to run
  64. * @param mixed $handling
  65. * - If null, handler will throw ErrorException
  66. * - If Throwable $t, throw $t with ErrorException attached as previous
  67. * - If callable, will invoke callback with ErrorException as argument
  68. * @param int $levels Error levels to catch, all errors by default
  69. * @return mixed Return what $callback returns, or what $handling retuns on error
  70. */
  71. public function withAll(callable $callback, $handling = null, int $levels = E_ALL)
  72. {
  73. $errors = [];
  74. $this->set(function (ErrorException $e) use (&$errors) {
  75. $errors[] = $e;
  76. }, $levels);
  77. $result = $callback();
  78. $this->restore();
  79. $error = empty($errors) ? null : $this->handle($handling, $errors, $result);
  80. return $error ?? $result;
  81. }
  82. /* ----------------- Private helpers --------------------------------------------- */
  83. // Get handler function
  84. private function getHandler($handling)
  85. {
  86. return function ($severity, $message, $file, $line) use ($handling) {
  87. $error = new ErrorException($message, 0, $severity, $file, $line);
  88. $this->handle($handling, $error);
  89. };
  90. }
  91. // Handle error according to $handlig type
  92. private function handle($handling, $error, $result = null)
  93. {
  94. if (is_callable($handling)) {
  95. return $handling($error, $result);
  96. }
  97. if (is_array($error)) {
  98. $error = array_shift($error);
  99. }
  100. if ($handling instanceof Throwable) {
  101. try {
  102. throw $error;
  103. } finally {
  104. throw $handling;
  105. }
  106. }
  107. throw $error;
  108. }
  109. }