5
5
#include "php_agent.h"
6
6
#include "php_call.h"
7
7
#include "php_user_instrument.h"
8
+ #include "php_error.h"
8
9
#include "php_execute.h"
9
10
#include "php_wrapper.h"
10
11
#include "fw_hooks.h"
@@ -36,7 +37,7 @@ NR_PHP_WRAPPER(nr_yii1_runWithParams_wrapper) {
36
37
(void )wraprec ;
37
38
NR_UNUSED_SPECIALFN ;
38
39
39
- NR_PHP_WRAPPER_REQUIRE_FRAMEWORK (NR_FW_YII );
40
+ NR_PHP_WRAPPER_REQUIRE_FRAMEWORK_VERSION (NR_FW_YII , 1 );
40
41
41
42
this_var = nr_php_scope_get (NR_EXECUTE_ORIG_ARGS TSRMLS_CC );
42
43
if (NULL == this_var ) {
@@ -88,6 +89,7 @@ NR_PHP_WRAPPER_END
88
89
* Enable Yii1 instrumentation.
89
90
*/
90
91
void nr_yii1_enable (TSRMLS_D ) {
92
+ NRPRG (framework_version ) = 1 ;
91
93
#if ZEND_MODULE_API_NO >= ZEND_8_0_X_API_NO \
92
94
&& !defined OVERWRITE_ZEND_EXECUTE_DATA
93
95
nr_php_wrap_user_function_before_after_clean (
@@ -117,7 +119,7 @@ NR_PHP_WRAPPER(nr_yii2_runWithParams_wrapper) {
117
119
(void )wraprec ;
118
120
NR_UNUSED_SPECIALFN ;
119
121
120
- NR_PHP_WRAPPER_REQUIRE_FRAMEWORK (NR_FW_YII );
122
+ NR_PHP_WRAPPER_REQUIRE_FRAMEWORK_VERSION (NR_FW_YII , 2 );
121
123
122
124
this_var = nr_php_scope_get (NR_EXECUTE_ORIG_ARGS TSRMLS_CC );
123
125
if (NULL == this_var ) {
@@ -150,10 +152,44 @@ NR_PHP_WRAPPER(nr_yii2_runWithParams_wrapper) {
150
152
}
151
153
NR_PHP_WRAPPER_END
152
154
155
+ /*
156
+ * Yii2: Report errors and exceptions when built-in ErrorHandler is enabled.
157
+ */
158
+ NR_PHP_WRAPPER (nr_yii2_error_handler_wrapper ) {
159
+ zval * exception = NULL ;
160
+
161
+ NR_UNUSED_SPECIALFN ;
162
+ (void )wraprec ;
163
+
164
+ NR_PHP_WRAPPER_REQUIRE_FRAMEWORK_VERSION (NR_FW_YII , 2 );
165
+
166
+ exception = nr_php_arg_get (1 , NR_EXECUTE_ORIG_ARGS TSRMLS_CC );
167
+ if (NULL == exception || !nr_php_is_zval_valid_object (exception )) {
168
+ nrl_verbosedebug (NRL_FRAMEWORK , "%s: exception is NULL or not an object" ,
169
+ __func__ );
170
+ NR_PHP_WRAPPER_CALL ;
171
+ goto end ;
172
+ }
173
+
174
+ NR_PHP_WRAPPER_CALL ;
175
+
176
+ if (NR_SUCCESS
177
+ != nr_php_error_record_exception (
178
+ NRPRG (txn ), exception , nr_php_error_get_priority (E_ERROR ), true,
179
+ "Uncaught exception " , & NRPRG (exception_filters ) TSRMLS_CC )) {
180
+ nrl_verbosedebug (NRL_FRAMEWORK , "%s: unable to record exception" , __func__ );
181
+ }
182
+
183
+ end :
184
+ nr_php_arg_release (& exception );
185
+ }
186
+ NR_PHP_WRAPPER_END
187
+
153
188
/*
154
189
* Enable Yii2 instrumentation.
155
190
*/
156
191
void nr_yii2_enable (TSRMLS_D ) {
192
+ NRPRG (framework_version ) = 2 ;
157
193
#if ZEND_MODULE_API_NO >= ZEND_8_0_X_API_NO \
158
194
&& !defined OVERWRITE_ZEND_EXECUTE_DATA
159
195
nr_php_wrap_user_function_before_after_clean (
@@ -168,4 +204,18 @@ void nr_yii2_enable(TSRMLS_D) {
168
204
nr_php_wrap_user_function (NR_PSTR ("yii\\base\\InlineAction::runWithParams" ),
169
205
nr_yii2_runWithParams_wrapper TSRMLS_CC );
170
206
#endif
207
+ /*
208
+ * Wrap Yii2 global error and exception handling methods.
209
+ * Given that: ErrorHandler::handleException(), ::handleError() and
210
+ * ::handleFatalError() all call ::logException($exception) at the right time,
211
+ * we will wrap this one to cover all cases.
212
+ * @see
213
+ * https://github.com/yiisoft/yii2/blob/master/framework/base/ErrorHandler.php
214
+ *
215
+ * Note: one can also set YII_ENABLE_ERROR_HANDLER constant to FALSE, this way
216
+ * allowing default PHP error handler to be intercepted by the NewRelic agent
217
+ * implementation.
218
+ */
219
+ nr_php_wrap_user_function (NR_PSTR ("yii\\base\\ErrorHandler::logException" ),
220
+ nr_yii2_error_handler_wrapper TSRMLS_CC );
171
221
}
0 commit comments