Throw when middleware class is missing or cannot be resolved

String middleware classes that do not exist or fail container
resolution are now validated at request time, matching route
handler behavior. Middleware that only implements one phase
(before/after) continues to be skipped for the other phase.

Fixes #696
pull/697/head
n0nag0n 1 week ago
parent 15cfdb01df
commit 60bf7921f2

@ -456,7 +456,22 @@ class Engine
$middlewareObject = method_exists($middleware, $eventName) === true ? [$middleware, $eventName] : false;
// If the middleware is a string, we need to create the object and then call the event.
} elseif (is_string($middleware) === true && method_exists($middleware, $eventName) === true) {
} elseif (is_string($middleware) === true) {
if (class_exists($middleware) === false) {
if (ob_get_level() > (getenv('PHPUNIT_TEST') ? 1 : 0)) {
ob_end_clean();
}
throw new Exception(
"Middleware class '$middleware' not found. "
. "Is it being correctly autoloaded with Flight::path()?"
);
}
if (method_exists($middleware, $eventName) === false) {
continue;
}
$resolvedClass = null;
// if there's a container assigned, we should use it to create the object
@ -464,14 +479,19 @@ class Engine
$resolvedClass = $this->dispatcher->resolveContainerClass($middleware, $params);
// otherwise just assume it's a plain jane class, so inject the engine
// just like in Dispatcher::invokeCallable()
} elseif (class_exists($middleware) === true) {
} else {
$resolvedClass = new $middleware($this);
}
// If something was resolved, create an array callable that will be passed in later.
if ($resolvedClass !== null) {
$middlewareObject = [$resolvedClass, $eventName];
if ($resolvedClass === null) {
if (ob_get_level() > (getenv('PHPUNIT_TEST') ? 1 : 0)) {
ob_end_clean();
}
throw new Exception("Middleware class '$middleware' could not be resolved.");
}
$middlewareObject = [$resolvedClass, $eventName];
}
// If nothing was resolved, go to the next thing

@ -899,6 +899,40 @@ class EngineTest extends TestCase
$this->expectOutputString('before456before123OKafter123456after123');
}
public function testMiddlewareMissingClassThrowsException(): void
{
$engine = new Engine();
$engine->route('/path1', function () {
echo 'OK';
})->addMiddleware('TotallyMissingMiddlewareClass');
$engine->request()->url = '/path1';
$this->expectException(Exception::class);
$this->expectExceptionMessage(
"Middleware class 'TotallyMissingMiddlewareClass' not found. "
. "Is it being correctly autoloaded with Flight::path()?"
);
$engine->start();
}
public function testMiddlewareMissingClassInGroupThrowsException(): void
{
$engine = new Engine();
$engine->group('', function ($router) {
$router->get('/path1', function () {
echo 'OK';
});
}, ['TotallyMissingMiddlewareClass']);
$engine->request()->url = '/path1';
$this->expectException(Exception::class);
$this->expectExceptionMessage(
"Middleware class 'TotallyMissingMiddlewareClass' not found. "
. "Is it being correctly autoloaded with Flight::path()?"
);
$engine->start();
}
public function testContainerBadClass()
{
$engine = new Engine();

Loading…
Cancel
Save