1: <?php
2: /**
3: * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
4: * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
5: *
6: * Licensed under The MIT License
7: * For full copyright and license information, please see the LICENSE.txt
8: * Redistributions of files must retain the above copyright notice.
9: *
10: * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
11: * @link https://cakephp.org CakePHP(tm) Project
12: * @since 2.0.0
13: * @license https://opensource.org/licenses/mit-license.php MIT License
14: */
15: namespace Cake\Console;
16:
17: use Cake\Error\BaseErrorHandler;
18: use Cake\Error\FatalErrorException;
19: use Cake\Error\PHP7ErrorException;
20: use Exception;
21:
22: /**
23: * Error Handler for Cake console. Does simple printing of the
24: * exception that occurred and the stack trace of the error.
25: */
26: class ConsoleErrorHandler extends BaseErrorHandler
27: {
28:
29: /**
30: * Standard error stream.
31: *
32: * @var \Cake\Console\ConsoleOutput
33: */
34: protected $_stderr;
35:
36: /**
37: * Options for this instance.
38: *
39: * @var array
40: */
41: protected $_options;
42:
43: /**
44: * Constructor
45: *
46: * @param array $options Options for the error handler.
47: */
48: public function __construct($options = [])
49: {
50: if (empty($options['stderr'])) {
51: $options['stderr'] = new ConsoleOutput('php://stderr');
52: }
53: $this->_stderr = $options['stderr'];
54: $this->_options = $options;
55: }
56:
57: /**
58: * Handle errors in the console environment. Writes errors to stderr,
59: * and logs messages if Configure::read('debug') is false.
60: *
61: * @param \Exception $exception Exception instance.
62: * @return void
63: * @throws \Exception When renderer class not found
64: * @see https://secure.php.net/manual/en/function.set-exception-handler.php
65: */
66: public function handleException(Exception $exception)
67: {
68: $this->_displayException($exception);
69: $this->_logException($exception);
70: $code = $exception->getCode();
71: $code = ($code && is_int($code)) ? $code : 1;
72: $this->_stop($code);
73: }
74:
75: /**
76: * Prints an exception to stderr.
77: *
78: * @param \Exception $exception The exception to handle
79: * @return void
80: */
81: protected function _displayException($exception)
82: {
83: $errorName = 'Exception:';
84: if ($exception instanceof FatalErrorException) {
85: $errorName = 'Fatal Error:';
86: }
87:
88: if ($exception instanceof PHP7ErrorException) {
89: $exception = $exception->getError();
90: }
91:
92: $message = sprintf(
93: '<error>%s</error> %s in [%s, line %s]',
94: $errorName,
95: $exception->getMessage(),
96: $exception->getFile(),
97: $exception->getLine()
98: );
99: $this->_stderr->write($message);
100: }
101:
102: /**
103: * Prints an error to stderr.
104: *
105: * Template method of BaseErrorHandler.
106: *
107: * @param array $error An array of error data.
108: * @param bool $debug Whether or not the app is in debug mode.
109: * @return void
110: */
111: protected function _displayError($error, $debug)
112: {
113: $message = sprintf(
114: '%s in [%s, line %s]',
115: $error['description'],
116: $error['file'],
117: $error['line']
118: );
119: $message = sprintf(
120: "<error>%s Error:</error> %s\n",
121: $error['error'],
122: $message
123: );
124: $this->_stderr->write($message);
125: }
126:
127: /**
128: * Stop the execution and set the exit code for the process.
129: *
130: * @param int $code The exit code.
131: * @return void
132: */
133: protected function _stop($code)
134: {
135: exit($code);
136: }
137: }
138: