1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* cloud solutions ZendSentry |
5
|
|
|
* |
6
|
|
|
* This source file is part of the cloud solutions ZendSentry package |
7
|
|
|
* |
8
|
|
|
* @package ZendSentry\Mvc\View\Http\ExceptionStrategy |
9
|
|
|
* @license New BSD License {@link /docs/LICENSE} |
10
|
|
|
* @copyright Copyright (c) 2016, cloud solutions OÜ |
11
|
|
|
*/ |
12
|
|
|
|
13
|
|
|
namespace ZendSentry\Mvc\View\Http; |
14
|
|
|
|
15
|
|
|
use Zend\EventManager\AbstractListenerAggregate; |
16
|
|
|
use Zend\EventManager\EventManagerInterface; |
17
|
|
|
use Zend\Http\Response as HttpResponse; |
18
|
|
|
use Zend\Mvc\Application; |
19
|
|
|
use Zend\Mvc\MvcEvent; |
20
|
|
|
use Zend\Stdlib\ResponseInterface as Response; |
21
|
|
|
use Zend\View\Model\ViewModel; |
22
|
|
|
|
23
|
|
|
/** |
24
|
|
|
* For the moment, this is just an augmented copy of the default ZF ExceptionStrategy |
25
|
|
|
* This is on purpose despite the duplication of code until the module stabilizes and it's clear what need exactly |
26
|
|
|
* |
27
|
|
|
* @package ZendSentry\Mvc\View\Http\ExceptionStrategy |
28
|
|
|
*/ |
29
|
|
|
class ExceptionStrategy extends AbstractListenerAggregate |
30
|
|
|
{ |
31
|
|
|
/** |
32
|
|
|
* Display exceptions? |
33
|
|
|
* @var bool |
34
|
|
|
*/ |
35
|
|
|
protected $displayExceptions = false; |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* Default Exception Message |
39
|
|
|
* @var string |
40
|
|
|
*/ |
41
|
|
|
protected $defaultExceptionMessage = 'Oh no. Something went wrong, but we have been notified. If you are testing, tell us your eventID: %s'; |
42
|
|
|
|
43
|
|
|
/** |
44
|
|
|
* Name of exception template |
45
|
|
|
* @var string |
46
|
|
|
*/ |
47
|
|
|
protected $exceptionTemplate = 'error'; |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* {@inheritDoc} |
51
|
|
|
*/ |
52
|
|
|
public function attach(EventManagerInterface $events, $priority = 1) |
53
|
|
|
{ |
54
|
|
|
$this->listeners[] = $events->attach(MvcEvent::EVENT_DISPATCH_ERROR, array($this, 'prepareExceptionViewModel')); |
55
|
|
|
$this->listeners[] = $events->attach(MvcEvent::EVENT_RENDER_ERROR, array($this, 'prepareExceptionViewModel')); |
56
|
|
|
} |
57
|
|
|
|
58
|
|
|
/** |
59
|
|
|
* Flag: display exceptions in error pages? |
60
|
|
|
* |
61
|
|
|
* @param bool $displayExceptions |
62
|
|
|
* @return ExceptionStrategy |
63
|
|
|
*/ |
64
|
|
|
public function setDisplayExceptions($displayExceptions) |
65
|
|
|
{ |
66
|
|
|
$this->displayExceptions = (bool) $displayExceptions; |
67
|
|
|
return $this; |
68
|
|
|
} |
69
|
|
|
|
70
|
|
|
/** |
71
|
|
|
* Should we display exceptions in error pages? |
72
|
|
|
* |
73
|
|
|
* @return bool |
74
|
|
|
*/ |
75
|
|
|
public function displayExceptions() |
76
|
|
|
{ |
77
|
|
|
return $this->displayExceptions; |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
/** |
81
|
|
|
* Set the default exception message |
82
|
|
|
* @param string $defaultExceptionMessage |
83
|
|
|
* @return self |
84
|
|
|
*/ |
85
|
|
|
public function setDefaultExceptionMessage($defaultExceptionMessage) |
86
|
|
|
{ |
87
|
|
|
$this->defaultExceptionMessage = $defaultExceptionMessage; |
88
|
|
|
return $this; |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
/** |
92
|
|
|
* Set the exception template |
93
|
|
|
* |
94
|
|
|
* @param string $exceptionTemplate |
95
|
|
|
* @return ExceptionStrategy |
96
|
|
|
*/ |
97
|
|
|
public function setExceptionTemplate($exceptionTemplate) |
98
|
|
|
{ |
99
|
|
|
$this->exceptionTemplate = (string) $exceptionTemplate; |
100
|
|
|
return $this; |
101
|
|
|
} |
102
|
|
|
|
103
|
|
|
/** |
104
|
|
|
* Retrieve the exception template |
105
|
|
|
* |
106
|
|
|
* @return string |
107
|
|
|
*/ |
108
|
|
|
public function getExceptionTemplate() |
109
|
|
|
{ |
110
|
|
|
return $this->exceptionTemplate; |
111
|
|
|
} |
112
|
|
|
|
113
|
|
|
/** |
114
|
|
|
* Create an exception view model, and set the HTTP status code |
115
|
|
|
* |
116
|
|
|
* @param MvcEvent $e |
117
|
|
|
* @return void |
118
|
|
|
*/ |
119
|
|
|
public function prepareExceptionViewModel(MvcEvent $e) |
120
|
|
|
{ |
121
|
|
|
// Do nothing if no error in the event |
122
|
|
|
$error = $e->getError(); |
123
|
|
|
if (empty($error)) { |
124
|
|
|
return; |
125
|
|
|
} |
126
|
|
|
|
127
|
|
|
// Do nothing if the result is a response object |
128
|
|
|
$result = $e->getResult(); |
129
|
|
|
if ($result instanceof Response) { |
|
|
|
|
130
|
|
|
return; |
131
|
|
|
} |
132
|
|
|
|
133
|
|
|
// Proceed to showing an error page with or without exception |
134
|
|
|
switch ($error) { |
135
|
|
|
case Application::ERROR_CONTROLLER_NOT_FOUND: |
136
|
|
|
case Application::ERROR_CONTROLLER_INVALID: |
137
|
|
|
case Application::ERROR_ROUTER_NO_MATCH: |
138
|
|
|
// Specifically not handling these |
139
|
|
|
return; |
140
|
|
|
|
141
|
|
|
case Application::ERROR_EXCEPTION: |
142
|
|
|
default: |
143
|
|
|
// check if there really is an exception |
144
|
|
|
// ZF also throws normal errors, for example: error-route-unauthorized |
145
|
|
|
// if there is no exception we have nothing to log |
146
|
|
|
if ($e->getParam('exception') == null) { |
147
|
|
|
return; |
148
|
|
|
} |
149
|
|
|
|
150
|
|
|
// Log exception to sentry by triggering an exception event |
151
|
|
|
$eventID = $e->getApplication()->getEventManager()->trigger('logException', $this, array('exception' => $e->getParam('exception'))); |
152
|
|
|
|
153
|
|
|
$model = new ViewModel(array( |
154
|
|
|
'message' => sprintf($this->defaultExceptionMessage, $eventID->last()), |
155
|
|
|
'exception' => $e->getParam('exception'), |
156
|
|
|
'display_exceptions' => $this->displayExceptions(), |
157
|
|
|
)); |
158
|
|
|
$model->setTemplate($this->getExceptionTemplate()); |
159
|
|
|
$e->setResult($model); |
160
|
|
|
|
161
|
|
|
$response = $e->getResponse(); |
162
|
|
|
if (!$response) { |
163
|
|
|
$response = new HttpResponse(); |
164
|
|
|
$response->setStatusCode(500); |
165
|
|
|
$e->setResponse($response); |
166
|
|
|
} else { |
167
|
|
|
$statusCode = $response->getStatusCode(); |
168
|
|
|
if ($statusCode === 200) { |
169
|
|
|
$response->setStatusCode(500); |
170
|
|
|
} |
171
|
|
|
} |
172
|
|
|
|
173
|
|
|
break; |
174
|
|
|
} |
175
|
|
|
} |
176
|
|
|
} |
|
|
|
|
177
|
|
|
|
This error could be the result of:
1. Missing dependencies
PHP Analyzer uses your
composer.json
file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects thecomposer.json
to be in the root folder of your repository.Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the
require
orrequire-dev
section?2. Missing use statement
PHP does not complain about undefined classes in
ìnstanceof
checks. For example, the following PHP code will work perfectly fine:If you have not tested against this specific condition, such errors might go unnoticed.