Skip to content

Commit 6a0d4f3

Browse files
authored
Merge pull request #54534 from nextcloud/fix/dispatcher/catch-type-errors-bad-request
fix(Dispatcher): Catch TypeErrors and turn them into bad request responses
2 parents 3f5c2cd + 9473f47 commit 6a0d4f3

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

lib/private/AppFramework/Http/Dispatcher.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,18 @@ private function executeController(Controller $controller, string $methodName):
201201
}
202202

203203
$this->eventLogger->start('controller:' . get_class($controller) . '::' . $methodName, 'App framework controller execution');
204-
$response = \call_user_func_array([$controller, $methodName], $arguments);
204+
try {
205+
$response = \call_user_func_array([$controller, $methodName], $arguments);
206+
} catch (\TypeError $e) {
207+
// Only intercept TypeErrors occuring on the first line, meaning that the invocation of the controller method failed.
208+
// Any other TypeError happens inside the controller method logic and should be logged as normal.
209+
if ($e->getFile() === $this->reflector->getFile() && $e->getLine() === $this->reflector->getStartLine()) {
210+
$this->logger->debug('Failed to call controller method: ' . $e->getMessage(), ['exception' => $e]);
211+
return new Response(Http::STATUS_BAD_REQUEST);
212+
}
213+
214+
throw $e;
215+
}
205216
$this->eventLogger->end('controller:' . get_class($controller) . '::' . $methodName);
206217

207218
if (!($response instanceof Response)) {

lib/private/AppFramework/Utility/ControllerMethodReflector.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,18 @@ class ControllerMethodReflector implements IControllerMethodReflector {
1818
private $types = [];
1919
private $parameters = [];
2020
private array $ranges = [];
21+
private int $startLine = 0;
22+
private string $file = '';
2123

2224
/**
2325
* @param object $object an object or classname
2426
* @param string $method the method which we want to inspect
2527
*/
2628
public function reflect($object, string $method) {
2729
$reflection = new \ReflectionMethod($object, $method);
30+
$this->startLine = $reflection->getStartLine();
31+
$this->file = $reflection->getFileName();
32+
2833
$docs = $reflection->getDocComment();
2934

3035
if ($docs !== false) {
@@ -134,4 +139,12 @@ public function getAnnotationParameter(string $name, string $key): string {
134139

135140
return '';
136141
}
142+
143+
public function getStartLine(): int {
144+
return $this->startLine;
145+
}
146+
147+
public function getFile(): string {
148+
return $this->file;
149+
}
137150
}

0 commit comments

Comments
 (0)