Merge pull request #54534 from nextcloud/fix/dispatcher/catch-type-errors-bad-request

fix(Dispatcher): Catch TypeErrors and turn them into bad request responses
This commit is contained in:
Ferdinand Thiessen 2025-09-05 01:24:54 +02:00 committed by GitHub
commit 6a0d4f33a8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 25 additions and 1 deletions

View file

@ -201,7 +201,18 @@ class Dispatcher {
}
$this->eventLogger->start('controller:' . get_class($controller) . '::' . $methodName, 'App framework controller execution');
$response = \call_user_func_array([$controller, $methodName], $arguments);
try {
$response = \call_user_func_array([$controller, $methodName], $arguments);
} catch (\TypeError $e) {
// Only intercept TypeErrors occuring on the first line, meaning that the invocation of the controller method failed.
// Any other TypeError happens inside the controller method logic and should be logged as normal.
if ($e->getFile() === $this->reflector->getFile() && $e->getLine() === $this->reflector->getStartLine()) {
$this->logger->debug('Failed to call controller method: ' . $e->getMessage(), ['exception' => $e]);
return new Response(Http::STATUS_BAD_REQUEST);
}
throw $e;
}
$this->eventLogger->end('controller:' . get_class($controller) . '::' . $methodName);
if (!($response instanceof Response)) {

View file

@ -18,6 +18,8 @@ class ControllerMethodReflector implements IControllerMethodReflector {
private $types = [];
private $parameters = [];
private array $ranges = [];
private int $startLine = 0;
private string $file = '';
/**
* @param object $object an object or classname
@ -25,6 +27,9 @@ class ControllerMethodReflector implements IControllerMethodReflector {
*/
public function reflect($object, string $method) {
$reflection = new \ReflectionMethod($object, $method);
$this->startLine = $reflection->getStartLine();
$this->file = $reflection->getFileName();
$docs = $reflection->getDocComment();
if ($docs !== false) {
@ -134,4 +139,12 @@ class ControllerMethodReflector implements IControllerMethodReflector {
return '';
}
public function getStartLine(): int {
return $this->startLine;
}
public function getFile(): string {
return $this->file;
}
}