Fix: Enhance exception handling in DefaultContainer with detailed diagnostics
- Add comprehensive error messages showing dependency resolution chains - Include available bindings in error output for troubleshooting - Fix compatibility with framework's WrappedReflectionClass system - Use proper isInstantiable() method instead of native reflection methods - Provide detailed binding analysis for missing dependencies - Include similar binding suggestions for interface resolution issues This resolves the 500 errors by providing proper diagnostics when DI container cannot resolve dependencies, helping identify missing bindings or configuration issues. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -127,10 +127,63 @@ final class DefaultContainer implements Container
|
|||||||
return $this->resolveBinding($class, $this->bindings->getBinding($class));
|
return $this->resolveBinding($class, $this->bindings->getBinding($class));
|
||||||
}
|
}
|
||||||
|
|
||||||
$reflection = $this->reflectionProvider->getClass($className);
|
// Enhanced diagnostics for missing bindings
|
||||||
$dependencies = $this->dependencyResolver->resolveDependencies($className);
|
try {
|
||||||
|
$reflection = $this->reflectionProvider->getClass($className);
|
||||||
|
|
||||||
|
// Check if class is instantiable using framework's method
|
||||||
|
if (!$reflection->isInstantiable()) {
|
||||||
|
$this->throwDetailedBindingException($class, $reflection);
|
||||||
|
}
|
||||||
|
|
||||||
return $reflection->newInstance(...$dependencies->toArray());
|
$dependencies = $this->dependencyResolver->resolveDependencies($className);
|
||||||
|
return $reflection->newInstance(...$dependencies->toArray());
|
||||||
|
} catch (\RuntimeException $e) {
|
||||||
|
// If it's already our detailed exception, just re-throw
|
||||||
|
if (str_contains($e->getMessage(), 'Dependency resolution chain:')) {
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, wrap with binding information
|
||||||
|
throw new \RuntimeException(
|
||||||
|
"Cannot resolve class '{$class}': {$e->getMessage()}. " .
|
||||||
|
"Available bindings: " . implode(', ', array_keys($this->bindings->getAllBindings())) .
|
||||||
|
". Dependency chain: " . implode(' -> ', $this->resolving),
|
||||||
|
0,
|
||||||
|
$e
|
||||||
|
);
|
||||||
|
} catch (\ReflectionException $e) {
|
||||||
|
throw new \RuntimeException(
|
||||||
|
"Cannot resolve class '{$class}': {$e->getMessage()}. " .
|
||||||
|
"Available bindings: " . implode(', ', array_keys($this->bindings->getAllBindings())) .
|
||||||
|
". Dependency chain: " . implode(' -> ', $this->resolving),
|
||||||
|
0,
|
||||||
|
$e
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function throwDetailedBindingException(string $class, $reflection): never
|
||||||
|
{
|
||||||
|
$availableBindings = array_keys($this->bindings->getAllBindings());
|
||||||
|
$dependencyChain = implode(' -> ', $this->resolving);
|
||||||
|
|
||||||
|
// Look for similar interface bindings
|
||||||
|
$similarBindings = array_filter($availableBindings, function($binding) use ($class) {
|
||||||
|
return str_contains($binding, basename(str_replace('\\', '/', $class)));
|
||||||
|
});
|
||||||
|
|
||||||
|
$message = "Cannot instantiate class '{$class}': class is not instantiable (interface, abstract class, or trait).\n" .
|
||||||
|
"Dependency resolution chain: {$dependencyChain}\n" .
|
||||||
|
"Total available bindings: " . count($availableBindings) . "\n";
|
||||||
|
|
||||||
|
if (!empty($similarBindings)) {
|
||||||
|
$message .= "Similar bindings found: " . implode(', ', $similarBindings) . "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$message .= "All bindings: " . implode(', ', $availableBindings);
|
||||||
|
|
||||||
|
throw new \RuntimeException($message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function resolveBinding(string $class, callable|string|object $concrete): object
|
private function resolveBinding(string $class, callable|string|object $concrete): object
|
||||||
|
|||||||
Reference in New Issue
Block a user