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: * Standard error stream.
30: *
31: * @var \Cake\Console\ConsoleOutput
32: */
33: protected $_stderr;
34:
35: /**
36: * Options for this instance.
37: *
38: * @var array
39: */
40: protected $_options;
41:
42: /**
43: * Constructor
44: *
45: * @param array $options Options for the error handler.
46: */
47: public function __construct($options = [])
48: {
49: if (empty($options['stderr'])) {
50: $options['stderr'] = new ConsoleOutput('php://stderr');
51: }
52: $this->_stderr = $options['stderr'];
53: $this->_options = $options;
54: }
55:
56: /**
57: * Handle errors in the console environment. Writes errors to stderr,
58: * and logs messages if Configure::read('debug') is false.
59: *
60: * @param \Exception $exception Exception instance.
61: * @return void
62: * @throws \Exception When renderer class not found
63: * @see https://secure.php.net/manual/en/function.set-exception-handler.php
64: */
65: public function handleException(Exception $exception)
66: {
67: $this->_displayException($exception);
68: $this->_logException($exception);
69: $code = $exception->getCode();
70: $code = ($code && is_int($code)) ? $code : 1;
71: $this->_stop($code);
72: }
73:
74: /**
75: * Prints an exception to stderr.
76: *
77: * @param \Exception $exception The exception to handle
78: * @return void
79: */
80: protected function _displayException($exception)
81: {
82: $errorName = 'Exception:';
83: if ($exception instanceof FatalErrorException) {
84: $errorName = 'Fatal Error:';
85: }
86:
87: if ($exception instanceof PHP7ErrorException) {
88: $exception = $exception->getError();
89: }
90:
91: $message = sprintf(
92: '<error>%s</error> %s in [%s, line %s]',
93: $errorName,
94: $exception->getMessage(),
95: $exception->getFile(),
96: $exception->getLine()
97: );
98: $this->_stderr->write($message);
99: }
100:
101: /**
102: * Prints an error to stderr.
103: *
104: * Template method of BaseErrorHandler.
105: *
106: * @param array $error An array of error data.
107: * @param bool $debug Whether or not the app is in debug mode.
108: * @return void
109: */
110: protected function _displayError($error, $debug)
111: {
112: $message = sprintf(
113: '%s in [%s, line %s]',
114: $error['description'],
115: $error['file'],
116: $error['line']
117: );
118: $message = sprintf(
119: "<error>%s Error:</error> %s\n",
120: $error['error'],
121: $message
122: );
123: $this->_stderr->write($message);
124: }
125:
126: /**
127: * Stop the execution and set the exit code for the process.
128: *
129: * @param int $code The exit code.
130: * @return void
131: */
132: protected function _stop($code)
133: {
134: exit($code);
135: }
136: }
137: