Completed
Branch refactor/kernels (dc422c)
by Atanas
02:02
created

ErrorHandler   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 126
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 38
dl 0
loc 126
rs 10
c 0
b 0
f 0
ccs 25
cts 25
cp 1
wmc 15

7 Methods

Rating   Name   Duplication   Size   Complexity  
A toPrettyErrorResponse() 0 6 1
A unregister() 0 3 2
A __construct() 0 3 1
A register() 0 3 2
A getResponse() 0 12 3
A toResponse() 0 12 3
A toDebugResponse() 0 18 3
1
<?php
2
/**
3
 * @package   WPEmerge
4
 * @author    Atanas Angelov <[email protected]>
5
 * @copyright 2018 Atanas Angelov
6
 * @license   https://www.gnu.org/licenses/gpl-2.0.html GPL-2.0
7
 * @link      https://wpemerge.com/
8
 */
9
10
namespace WPEmerge\Exceptions;
11
12
use Exception as PhpException;
13
use Psr\Http\Message\ResponseInterface;
14
use Whoops\RunInterface;
15
use WPEmerge\Csrf\InvalidCsrfTokenException;
16
use WPEmerge\Facades\Response;
17
use WPEmerge\Requests\RequestInterface;
18
use WPEmerge\Routing\NotFoundException;
19
use WPEmerge\Support\Arr;
20
21
class ErrorHandler implements ErrorHandlerInterface {
22
	/**
23
	 * Pretty handler.
24
	 *
25
	 * @var RunInterface|null
26
	 */
27
	protected $whoops = null;
28
29
	/**
30
	 * Whether debug mode is enabled.
31
	 *
32
	 * @var boolean
33
	 */
34
	protected $debug = false;
35
36
	/**
37
	 * Constructor.
38
	 *
39
	 * @codeCoverageIgnore
40
	 * @param RunInterface|null $whoops
41
	 * @param boolean           $debug
42
	 */
43
	public function __construct( $whoops, $debug = false ) {
44
		$this->whoops = $whoops;
45
		$this->debug = $debug;
46
	}
47
48
	/**
49
	 * {@inheritDoc}
50
	 * @codeCoverageIgnore
51
	 */
52
	public function register() {
53
		if ( $this->whoops !== null ) {
54
			$this->whoops->register();
55
		}
56
	}
57
58
	/**
59
	 * {@inheritDoc}
60
	 * @codeCoverageIgnore
61
	 */
62
	public function unregister() {
63
		if ( $this->whoops !== null ) {
64
			$this->whoops->unregister();
65
		}
66
	}
67
68
	/**
69
	 * Convert an exception to a ResponseInterface instance if possible.
70
	 *
71
	 * @param  PhpException            $exception
72
	 * @return ResponseInterface|false
73
	 */
74 2
	protected function toResponse( $exception ) {
75
		// @codeCoverageIgnoreStart
76
		if ( $exception instanceof InvalidCsrfTokenException ) {
77
			wp_nonce_ays( '' );
78
		}
79
		// @codeCoverageIgnoreEnd
80
81 2
		if ( $exception instanceof NotFoundException ) {
82 1
			return Response::error( 404 );
83
		}
84
85 1
		return false;
86
	}
87
88
	/**
89
	 * Convert an exception to a debug ResponseInterface instance if possible.
90
	 *
91
	 * @throws PhpException
92
	 * @param  RequestInterface  $request
93
	 * @param  PhpException      $exception
94
	 * @return ResponseInterface
95
	 */
96 3
	protected function toDebugResponse( RequestInterface $request, PhpException $exception ) {
97 3
		if ( $request->isAjax() ) {
98 1
			return Response::json( [
99 1
				'message' => $exception->getMessage(),
100 1
				'exception' => get_class( $exception ),
101 1
				'file' => $exception->getFile(),
102 1
				'line' => $exception->getLine(),
103 1
				'trace' => array_map( function ( $trace ) {
104 1
					return Arr::except( $trace, ['args'] );
105 1
				}, $exception->getTrace() ),
106 1
			] )->withStatus( 500 );
107
		}
108
109 2
		if ( $this->whoops !== null ) {
110 1
			return $this->toPrettyErrorResponse( $exception );
111
		}
112
113 1
		throw $exception;
114
	}
115
116
	/**
117
	 * Convert an exception to a pretty error response.
118
	 *
119
	 * @codeCoverageIgnore
120
	 * @param  PhpException      $exception
121
	 * @return ResponseInterface
122
	 */
123
	protected function toPrettyErrorResponse( $exception ) {
124
		$method = RunInterface::EXCEPTION_HANDLER;
125
		ob_start();
126
		$this->whoops->$method( $exception );
127
		$response = ob_get_clean();
128
		return Response::output( $response )->withStatus( 500 );
129
	}
130
131
	/**
132
	 * {@inheritDoc}
133
	 * @throws PhpException
134
	 */
135 5
	public function getResponse( RequestInterface $request, PhpException $exception ) {
136 5
		$response = $this->toResponse( $exception );
137
138 5
		if ( $response !== false ) {
139 1
			return $response;
140
		}
141
142 4
		if ( ! $this->debug ) {
143 1
			return Response::error( 500 );
144
		}
145
146 3
		return $this->toDebugResponse( $request, $exception );
147
	}
148
}
149