1111
1212namespace Inhere \Library \Components ;
1313
14+ use Inhere \Library \Helpers \Obj ;
1415use Inhere \Library \Helpers \PhpHelper ;
1516use Monolog \Logger ;
1617use Psr \Log \LoggerInterface ;
2829 */
2930class ErrorHandler
3031{
31- private $ logger ;
32+ protected $ logger ;
3233
3334 private $ previousExceptionHandler ;
3435 private $ uncaughtExceptionLevel ;
@@ -38,16 +39,21 @@ class ErrorHandler
3839 private $ handleOnlyReportedErrors ;
3940
4041 private $ hasFatalErrorHandler ;
41- private $ fatalLevel ;
42- private $ reservedMemory ;
43- private static $ fatalErrors = [E_ERROR , E_PARSE , E_CORE_ERROR , E_COMPILE_ERROR , E_USER_ERROR ];
42+ protected $ fatalLevel ;
43+ protected $ reservedMemory ;
44+ public static $ fatalErrors = [E_ERROR , E_PARSE , E_CORE_ERROR , E_COMPILE_ERROR , E_USER_ERROR ];
45+
46+ private $ exitOnHandled = true ;
4447
4548 /**
4649 * ErrorHandler constructor.
4750 * @param LoggerInterface $logger
51+ * @param array $options
4852 */
49- public function __construct (LoggerInterface $ logger )
53+ public function __construct (LoggerInterface $ logger, array $ options = [] )
5054 {
55+ Obj::smartConfigure ($ this , $ options );
56+
5157 $ this ->logger = $ logger ;
5258 }
5359
@@ -79,29 +85,45 @@ class_exists(LogLevel::class);
7985 return $ this ;
8086 }
8187
88+ /**
89+ * @param null $level
90+ * @param bool $callPrevious
91+ */
8292 public function registerExceptionHandler ($ level = null , $ callPrevious = true )
8393 {
84- $ prev = set_exception_handler (array ( $ this , 'handleException ' ) );
94+ $ prev = set_exception_handler ([ $ this , 'handleException ' ] );
8595 $ this ->uncaughtExceptionLevel = $ level ;
96+
8697 if ($ callPrevious && $ prev ) {
8798 $ this ->previousExceptionHandler = $ prev ;
8899 }
89100 }
90101
91- public function registerErrorHandler (array $ levelMap = array (), $ callPrevious = true , $ errorTypes = -1 , $ handleOnlyReportedErrors = true )
102+ /**
103+ * @param array $levelMap
104+ * @param bool $callPrevious
105+ * @param int $errorTypes
106+ * @param bool $handleOnlyReportedErrors
107+ */
108+ public function registerErrorHandler (array $ levelMap = [], $ callPrevious = true , $ errorTypes = -1 , $ handleOnlyReportedErrors = true )
92109 {
93- $ prev = set_error_handler (array ( $ this , 'handleError ' ) , $ errorTypes );
110+ $ prev = set_error_handler ([ $ this , 'handleError ' ] , $ errorTypes );
94111 $ this ->errorLevelMap = array_replace ($ this ->defaultErrorLevelMap (), $ levelMap );
112+
95113 if ($ callPrevious ) {
96114 $ this ->previousErrorHandler = $ prev ?: true ;
97115 }
98116
99117 $ this ->handleOnlyReportedErrors = $ handleOnlyReportedErrors ;
100118 }
101119
120+ /**
121+ * @param null $level
122+ * @param int $reservedMemorySize
123+ */
102124 public function registerFatalHandler ($ level = null , $ reservedMemorySize = 20 )
103125 {
104- register_shutdown_function (array ( $ this , 'handleFatalError ' ) );
126+ register_shutdown_function ([ $ this , 'handleFatalError ' ] );
105127
106128 $ this ->reservedMemory = str_repeat (' ' , 1024 * $ reservedMemorySize );
107129 $ this ->fatalLevel = $ level ;
@@ -130,22 +152,23 @@ protected function defaultErrorLevelMap()
130152 }
131153
132154 /**
133- * @private
134155 * @param \Throwable $e
135156 */
136157 public function handleException ($ e )
137158 {
138159 $ this ->logger ->log (
139160 $ this ->uncaughtExceptionLevel ?? LogLevel::ERROR ,
140161 sprintf ('Uncaught Exception %s: "%s" at %s line %s ' , get_class ($ e ), $ e ->getMessage (), $ e ->getFile (), $ e ->getLine ()),
141- array ( 'exception ' => $ e)
162+ [ 'exception ' => $ e]
142163 );
143164
144165 if ($ this ->previousExceptionHandler ) {
145166 PhpHelper::call ($ this ->previousExceptionHandler , $ e );
146167 }
147168
148- exit (255 );
169+ if ($ this ->exitOnHandled ) {
170+ exit (255 );
171+ }
149172 }
150173
151174 /**
@@ -166,21 +189,28 @@ public function handleError($code, $message, $file = '', $line = 0, array $conte
166189 // fatal error codes are ignored if a fatal error handler is present as well to avoid duplicate log entries
167190 if (!$ this ->hasFatalErrorHandler || !in_array ($ code , self ::$ fatalErrors , true )) {
168191 $ level = $ this ->errorLevelMap [$ code ] ?? LogLevel::CRITICAL ;
169- $ this ->logger ->log ($ level , self ::codeToString ($ code ).': ' .$ message , array ('code ' => $ code , 'message ' => $ message , 'file ' => $ file , 'line ' => $ line ));
192+ $ this ->logger ->log ($ level , self ::codeToString ($ code ).': ' .$ message , [
193+ 'code ' => $ code ,
194+ 'message ' => $ message ,
195+ 'file ' => $ file ,
196+ 'line ' => $ line ,
197+ 'catcher ' => __METHOD__ ,
198+ ]);
170199 }
171200
172201 if ($ this ->previousErrorHandler === true ) {
173202 return false ;
174203 }
175204
176205 if ($ this ->previousErrorHandler ) {
177- return call_user_func ($ this ->previousErrorHandler , $ code , $ message , $ file , $ line , $ context );
206+ return PhpHelper:: call ($ this ->previousErrorHandler , [ $ code , $ message , $ file , $ line , $ context] );
178207 }
179208
180209 return false ;
181210 }
182211
183212 /**
213+ * handleFatalError
184214 * @private
185215 */
186216 public function handleFatalError ()
@@ -192,7 +222,12 @@ public function handleFatalError()
192222 $ this ->logger ->log (
193223 $ this ->fatalLevel ?? LogLevel::ALERT ,
194224 'Fatal Error ( ' .self ::codeToString ($ lastError ['type ' ]).'): ' .$ lastError ['message ' ],
195- array ('code ' => $ lastError ['type ' ], 'message ' => $ lastError ['message ' ], 'file ' => $ lastError ['file ' ], 'line ' => $ lastError ['line ' ])
225+ [
226+ 'code ' => $ lastError ['type ' ],
227+ 'message ' => $ lastError ['message ' ],
228+ 'file ' => $ lastError ['file ' ],
229+ 'line ' => $ lastError ['line ' ]
230+ ]
196231 );
197232
198233 if ($ this ->logger instanceof Logger) {
@@ -205,7 +240,7 @@ public function handleFatalError()
205240 }
206241 }
207242
208- private static function codeToString ($ code )
243+ public static function codeToString ($ code )
209244 {
210245 switch ($ code ) {
211246 case E_ERROR :
@@ -242,4 +277,20 @@ private static function codeToString($code)
242277
243278 return 'Unknown PHP error ' ;
244279 }
280+
281+ /**
282+ * @return bool
283+ */
284+ public function isExitOnHandled (): bool
285+ {
286+ return $ this ->exitOnHandled ;
287+ }
288+
289+ /**
290+ * @param bool $exitOnHandled
291+ */
292+ public function setExitOnHandled ($ exitOnHandled )
293+ {
294+ $ this ->exitOnHandled = (bool )$ exitOnHandled ;
295+ }
245296}
0 commit comments