Enable Discovery debug logging for production troubleshooting

- Add DISCOVERY_LOG_LEVEL=debug
- Add DISCOVERY_SHOW_PROGRESS=true
- Temporary changes for debugging InitializerProcessor fixes on production
This commit is contained in:
2025-08-11 20:13:26 +02:00
parent 59fd3dd3b1
commit 55a330b223
3683 changed files with 2956207 additions and 16948 deletions

View File

@@ -0,0 +1,278 @@
<?php
declare(strict_types=1);
namespace App\Framework\Discovery\Exceptions;
use App\Framework\Exception\ErrorCode;
use App\Framework\Exception\ExceptionContext;
use App\Framework\Exception\FrameworkException;
/**
* Base exception for Discovery system operations
*
* Provides specialized error handling for discovery-related
* operations with appropriate error codes and recovery hints.
*/
final class DiscoveryException extends FrameworkException
{
/**
* Discovery process failed due to memory constraints
*/
public static function memoryExhausted(string $operation, int $currentMemory, int $memoryLimit): self
{
$context = ExceptionContext::forOperation('discovery.memory_exhausted', 'DiscoveryService')
->withData([
'operation' => $operation,
'current_memory_mb' => round($currentMemory / 1024 / 1024, 2),
'memory_limit_mb' => round($memoryLimit / 1024 / 1024, 2),
'memory_usage_percent' => round(($currentMemory / $memoryLimit) * 100, 1),
])
->withDebug([
'current_memory_bytes' => $currentMemory,
'memory_limit_bytes' => $memoryLimit,
]);
return self::fromContext(
"Discovery operation '{$operation}' failed due to memory exhaustion",
$context,
ErrorCode::MEMORY_LIMIT_EXCEEDED
)->withRetryAfter(300); // Suggest retry after 5 minutes
}
/**
* Directory scanning failed
*/
public static function scanFailed(string $directory, string $reason, ?\Throwable $previous = null): self
{
$context = ExceptionContext::forOperation('discovery.scan_failed', 'FileScanner')
->withData([
'directory' => $directory,
'reason' => $reason,
'is_readable' => is_readable($directory),
'exists' => file_exists($directory),
]);
return self::fromContext(
"Failed to scan directory '{$directory}': {$reason}",
$context,
ErrorCode::FILESYSTEM_READ_ERROR,
$previous
);
}
/**
* Cache operation failed
*/
public static function cacheFailed(string $operation, string $key, ?\Throwable $previous = null): self
{
$context = ExceptionContext::forOperation('discovery.cache_failed', 'DiscoveryCacheManager')
->withData([
'cache_operation' => $operation,
'cache_key' => $key,
])
->withDebug([
'key_hash' => md5($key),
'operation_timestamp' => time(),
]);
return self::fromContext(
"Discovery cache operation '{$operation}' failed for key '{$key}'",
$context,
ErrorCode::CACHE_OPERATION_FAILED,
$previous
);
}
/**
* File processing failed
*/
public static function fileProcessingFailed(string $file, string $reason, ?\Throwable $previous = null): self
{
$context = ExceptionContext::forOperation('discovery.file_processing_failed', 'FileProcessor')
->withData([
'file_path' => $file,
'file_size' => file_exists($file) ? filesize($file) : null,
'file_extension' => pathinfo($file, PATHINFO_EXTENSION),
'reason' => $reason,
]);
return self::fromContext(
"Failed to process file '{$file}': {$reason}",
$context,
ErrorCode::FILE_PROCESSING_FAILED,
$previous
);
}
/**
* Attribute reflection failed
*/
public static function attributeReflectionFailed(string $className, string $attributeType, ?\Throwable $previous = null): self
{
$context = ExceptionContext::forOperation('discovery.attribute_reflection_failed', 'AttributeProcessor')
->withData([
'class_name' => $className,
'attribute_type' => $attributeType,
'class_exists' => class_exists($className),
]);
return self::fromContext(
"Failed to reflect attribute '{$attributeType}' on class '{$className}'",
$context,
ErrorCode::REFLECTION_FAILED,
$previous
);
}
/**
* Memory guard emergency stop
*/
public static function emergencyStop(string $reason, array $memoryStats): self
{
$context = ExceptionContext::forOperation('discovery.emergency_stop', 'MemoryGuard')
->withData([
'reason' => $reason,
'memory_usage_mb' => round($memoryStats['current_usage'] / 1024 / 1024, 2),
'memory_limit_mb' => round($memoryStats['memory_limit'] / 1024 / 1024, 2),
'memory_pressure' => $memoryStats['memory_pressure'] ?? 'unknown',
])
->withDebug($memoryStats);
return self::fromContext(
"Discovery process stopped by memory guard: {$reason}",
$context,
ErrorCode::EMERGENCY_STOP_TRIGGERED
);
}
/**
* Configuration validation failed
*/
public static function configurationInvalid(string $field, string $reason): self
{
$context = ExceptionContext::forOperation('discovery.configuration_invalid', 'DiscoveryConfiguration')
->withData([
'invalid_field' => $field,
'validation_error' => $reason,
]);
return self::fromContext(
"Discovery configuration invalid - {$field}: {$reason}",
$context,
ErrorCode::VAL_CONFIGURATION_INVALID
);
}
/**
* Discovery timeout
*/
public static function timeout(int $timeoutSeconds, int $actualSeconds): self
{
$context = ExceptionContext::forOperation('discovery.timeout', 'DiscoveryService')
->withData([
'timeout_seconds' => $timeoutSeconds,
'actual_seconds' => $actualSeconds,
'exceeded_by_seconds' => $actualSeconds - $timeoutSeconds,
]);
return self::fromContext(
"Discovery operation timed out after {$actualSeconds}s (limit: {$timeoutSeconds}s)",
$context,
ErrorCode::OPERATION_TIMEOUT
)->withRetryAfter(60); // Suggest retry after 1 minute
}
/**
* Concurrent discovery conflict
*/
public static function concurrentDiscovery(string $lockId): self
{
$context = ExceptionContext::forOperation('discovery.concurrent_conflict', 'DiscoveryService')
->withData([
'lock_id' => $lockId,
'conflict_type' => 'concurrent_discovery',
]);
return self::fromContext(
"Discovery already in progress (lock: {$lockId})",
$context,
ErrorCode::RESOURCE_CONFLICT
)->withRetryAfter(30); // Suggest retry after 30 seconds
}
/**
* Corrupted discovery data
*/
public static function corruptedData(string $source, string $reason): self
{
$context = ExceptionContext::forOperation('discovery.corrupted_data', 'DiscoveryService')
->withData([
'data_source' => $source,
'corruption_reason' => $reason,
]);
return self::fromContext(
"Discovery data corrupted in {$source}: {$reason}",
$context,
ErrorCode::DATA_CORRUPTION_DETECTED
);
}
/**
* Insufficient permissions
*/
public static function insufficientPermissions(string $path, string $requiredPermission): self
{
$context = ExceptionContext::forOperation('discovery.insufficient_permissions', 'FileScanner')
->withData([
'path' => $path,
'required_permission' => $requiredPermission,
'current_permissions' => file_exists($path) ? substr(sprintf('%o', fileperms($path)), -4) : null,
]);
return self::fromContext(
"Insufficient permissions to access '{$path}' (required: {$requiredPermission})",
$context,
ErrorCode::PERMISSION_DENIED
);
}
/**
* Resource limit exceeded
*/
public static function resourceLimitExceeded(string $resource, int $current, int $limit): self
{
$context = ExceptionContext::forOperation('discovery.resource_limit_exceeded', 'DiscoveryService')
->withData([
'resource_type' => $resource,
'current_usage' => $current,
'resource_limit' => $limit,
'usage_percentage' => round(($current / $limit) * 100, 1),
]);
return self::fromContext(
"Resource limit exceeded for {$resource}: {$current}/{$limit}",
$context,
ErrorCode::RESOURCE_LIMIT_EXCEEDED
)->withRetryAfter(60);
}
/**
* Dependency missing
*/
public static function dependencyMissing(string $dependency, string $requiredFor): self
{
$context = ExceptionContext::forOperation('discovery.dependency_missing', 'DiscoveryService')
->withData([
'missing_dependency' => $dependency,
'required_for' => $requiredFor,
]);
return self::fromContext(
"Missing dependency '{$dependency}' required for {$requiredFor}",
$context,
ErrorCode::DEPENDENCY_MISSING
);
}
}