Skip to content

Commit f159113

Browse files
razvanphplavarou
authored andcommitted
feat(agent): Add Yii v2 ErrorHandler wrapper
1 parent ed7db9a commit f159113

File tree

1 file changed

+52
-2
lines changed

1 file changed

+52
-2
lines changed

agent/fw_yii.c

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "php_agent.h"
66
#include "php_call.h"
77
#include "php_user_instrument.h"
8+
#include "php_error.h"
89
#include "php_execute.h"
910
#include "php_wrapper.h"
1011
#include "fw_hooks.h"
@@ -36,7 +37,7 @@ NR_PHP_WRAPPER(nr_yii1_runWithParams_wrapper) {
3637
(void)wraprec;
3738
NR_UNUSED_SPECIALFN;
3839

39-
NR_PHP_WRAPPER_REQUIRE_FRAMEWORK(NR_FW_YII);
40+
NR_PHP_WRAPPER_REQUIRE_FRAMEWORK_VERSION(NR_FW_YII, 1);
4041

4142
this_var = nr_php_scope_get(NR_EXECUTE_ORIG_ARGS TSRMLS_CC);
4243
if (NULL == this_var) {
@@ -88,6 +89,7 @@ NR_PHP_WRAPPER_END
8889
* Enable Yii1 instrumentation.
8990
*/
9091
void nr_yii1_enable(TSRMLS_D) {
92+
NRPRG(framework_version) = 1;
9193
#if ZEND_MODULE_API_NO >= ZEND_8_0_X_API_NO \
9294
&& !defined OVERWRITE_ZEND_EXECUTE_DATA
9395
nr_php_wrap_user_function_before_after_clean(
@@ -117,7 +119,7 @@ NR_PHP_WRAPPER(nr_yii2_runWithParams_wrapper) {
117119
(void)wraprec;
118120
NR_UNUSED_SPECIALFN;
119121

120-
NR_PHP_WRAPPER_REQUIRE_FRAMEWORK(NR_FW_YII);
122+
NR_PHP_WRAPPER_REQUIRE_FRAMEWORK_VERSION(NR_FW_YII, 2);
121123

122124
this_var = nr_php_scope_get(NR_EXECUTE_ORIG_ARGS TSRMLS_CC);
123125
if (NULL == this_var) {
@@ -150,10 +152,44 @@ NR_PHP_WRAPPER(nr_yii2_runWithParams_wrapper) {
150152
}
151153
NR_PHP_WRAPPER_END
152154

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+
153188
/*
154189
* Enable Yii2 instrumentation.
155190
*/
156191
void nr_yii2_enable(TSRMLS_D) {
192+
NRPRG(framework_version) = 2;
157193
#if ZEND_MODULE_API_NO >= ZEND_8_0_X_API_NO \
158194
&& !defined OVERWRITE_ZEND_EXECUTE_DATA
159195
nr_php_wrap_user_function_before_after_clean(
@@ -168,4 +204,18 @@ void nr_yii2_enable(TSRMLS_D) {
168204
nr_php_wrap_user_function(NR_PSTR("yii\\base\\InlineAction::runWithParams"),
169205
nr_yii2_runWithParams_wrapper TSRMLS_CC);
170206
#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);
171221
}

0 commit comments

Comments
 (0)