Directly invoking proxy within pre hook crashes terminal
nmeri17 opened this issue · 2 comments
I have a high-level function that allows consumers run arbitrary functions before target methods.
foreach ($baseActions as $hooker => $action)
$hookers[$hooker] = function ($proxy, $concrete, $calledMethod, $parameters, &$earlyReturn) use ($action) {
$earlyReturn = true; // since handlers want to take responsibility of calling underlying concrete, not ProxyManager
return call_user_func_array($action, [
$concrete,
$calledMethod, $parameters
]);
};
One of such arbitrary functionality involves a handler that does something similar to the following
public function safeCall (Failable $target, string $method, $parameters) { // safeCall is passed to $baseActions
try {
return call_user_func_array([$target, $method], $parameters);
}
catch (\Throwable $e) {
// do something with $e
// use nullObjectFactory to prepare some dummy result based on $target->$method return type
$target->failedOperation($method);
return $dummyResult;
}
}
All other handlers work correctly, except this one with the line $target->failedOperation($method);
. When I was using AccessInterceptorValueHolderFactory
, safeCall
received parent/original object. By the time user-land caller tries reading $target->getLastFailed();
, it's now looking at a proxy where that property is null
trait FailableTrait {
protected $erroneousMethod; // always null!!
public function getLastFailed ():?string {
return $this->erroneousMethod;
}
public function failedOperation (string $method):void {
$this->erroneousMethod = $method;
}
}
Now, if I switch the proxy from AccessInterceptorValueHolderFactory
to AccessInterceptorScopeLocalizerFactory
or if I pass $proxy
instead of $concrete
so handler can mutate what's passed to user-land, test terminal/CLI crashes every time this line executes call_user_func_array([$target, $method], $parameters);
How do you suggest I invoke target within a sandbox while mutating target?
I can confirm that terminal crashing was of my own making. It's unfortunate that neither the library nor php was able to detect max call stack and shutdown gracefully like it does with fatal errors
I faintly recall reading a warning not to invoke proxy within the handler, but I don't remember where. That turned out to be the reason behind the recursion crashing terminal. I call the returned proxy, it delegates to my handler, which in turn calls the same method on proxy in a vicious cycle
So, in order to manually invoke proxy, I passed it as additional method to safeCall
, but instead of calling it again, I call $concrete
. Then, in the try catch, I call failedOperation
on the proxy since that's the instance that will be read in user land
neither the library nor php was able to detect max call stack and shutdown gracefully like it does with fatal errors
AFAIK, only XDebug does that.