HandleUncaughtError::setErrorHandler()
last analyzed

Size

Total Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 1
ccs 0
cts 0
cp 0
nc 1
1
<?php
2
3
namespace Jasny\ErrorHandler;
4
5
/**
6
 * Trait for handling uncaught errors using PHP's error handler
7
 */
8
trait HandleUncaughtError
9
{
10
    /**
11
     * @var callable|false
12
     */
13
    protected $chainedErrorHandler;
14
15
    /**
16
     * Convert fatal errors to exceptions
17
     * @var boolean
18
     */
19
    protected $convertFatalErrors = false;
20
    
21
    /**
22
     * Log the following error types (in addition to caugth errors)
23
     * @var int
24
     */
25
    protected $logErrorTypes = 0;
26
    
27
28
    /**
29
     * Run the fatal error callback
30
     * 
31
     * @param \Exception|\Error $error
32
     * @return void
33
     */
34
    abstract protected function callOnFatalError($error);
35
36
    /**
37
     * Wrapper method for `error_reporting`
38
     * 
39
     * @return int
40
     */
41
    abstract protected function errorReporting();
42
43
    /**
44
     * Wrapper method for `set_error_handler`
45
     * 
46
     * @param callable $callback
47
     * @param int      $error_types
48
     * @return callable|null
49
     */
50
    abstract protected function setErrorHandler($callback, $error_types = E_ALL);
51
52
    /**
53
     * Register the shutdown function
54
     * @return void
55
     */
56
    abstract protected function initShutdownFunction();
57
58
    /**
59
     * Log an error or exception
60
     * 
61
     * @param \Exception|\Error $error
62
     * @return void
63
     */
64
    abstract public function log($error);
65
66
67
    /**
68
     * Get the error handler that has been replaced.
69
     * 
70
     * @return callable|false|null
71
     */
72 2
    public function getChainedErrorHandler()
73
    {
74 2
        return $this->chainedErrorHandler;
75
    }
76
    
77
    /**
78
     * Get the types of errors that will be logged
79
     * 
80
     * @return int  Binary set of E_* constants
81
     */
82 82
    public function getLoggedErrorTypes()
83
    {
84 82
        return $this->logErrorTypes;
85
    }
86
87
    /**
88
     * Log these types of errors or exceptions
89
     * 
90
     * @param int $type  E_* contants as binary set
91
     */
92 68
    protected function logUncaughtErrors($type)
93
    {
94 68
        $this->logErrorTypes |= $type;
95
96 68
        $unhandled = E_ERROR | E_PARSE | E_CORE_ERROR | E_COMPILE_ERROR;
97
98 68
        if ($type & ~$unhandled) {
99 58
            $this->initErrorHandler();
100
        }
101
102 68
        if ($type & $unhandled) {
103 32
            $this->initShutdownFunction();
104
        }
105 68
    }
106
107
    
108
    /**
109
     * Use the global error handler to convert E_USER_ERROR and E_RECOVERABLE_ERROR to an ErrorException
110
     */
111 28
    public function converErrorsToExceptions()
112
    {
113 28
        $this->convertFatalErrors = true;
114 28
        $this->initErrorHandler();
115 28
    }
116
    
117
118
    /**
119
     * Use the global error handler
120
     */
121 86
    protected function initErrorHandler()
122
    {
123 86
        if (!isset($this->chainedErrorHandler)) {
124 86
            $this->chainedErrorHandler = $this->setErrorHandler([$this, 'handleError']) ?: false;
125
        }
126 86
    }
127
    
128
    /**
129
     * Uncaught error handler
130
     * @ignore
131
     * 
132
     * @param int    $type
133
     * @param string $message
134
     * @param string $file
135
     * @param int    $line
136
     * @param array  $context
137
     */
138 54
    public function handleError($type, $message, $file, $line, $context)
139
    {
140 54
        if ($this->errorReporting() & $type) {
141 54
            $error = new \ErrorException($message, 0, $type, $file, $line);
142
143 54
            if ($this->convertFatalErrors && ($type & (E_RECOVERABLE_ERROR | E_USER_ERROR))) {
144 8
                throw $error;
145
            }
146
147 46
            if ($this->getLoggedErrorTypes() & $type) {
148 14
                $this->log($error);
149
            }
150
        }
151
        
152 46
        return $this->chainedErrorHandler
153 2
            ? call_user_func($this->chainedErrorHandler, $type, $message, $file, $line, $context)
154 46
            : false;
155
    }
156
}
157
158