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:
@@ -4,58 +4,143 @@ declare(strict_types=1);
|
||||
|
||||
namespace App\Framework\Exception;
|
||||
|
||||
final class DatabaseException extends FrameworkException
|
||||
/**
|
||||
* Database-spezifische Exception mit vorgefertigten Error Codes
|
||||
*/
|
||||
class DatabaseException extends FrameworkException
|
||||
{
|
||||
public static function connectionFailed(string $dsn, \Throwable $previous): self
|
||||
{
|
||||
$context = ExceptionContext::forOperation('database.connect', 'PDO')
|
||||
// === Factory Methods für häufige Database Errors ===
|
||||
|
||||
public static function connectionFailed(
|
||||
?string $details = null,
|
||||
?\Throwable $previous = null
|
||||
): static {
|
||||
$context = ExceptionContext::forOperation('database.connect', 'Database')
|
||||
->withData(['details' => $details]);
|
||||
|
||||
$message = $details ? "Database connection failed: $details" : null;
|
||||
|
||||
return static::create(
|
||||
ErrorCode::DB_CONNECTION_FAILED,
|
||||
$message,
|
||||
$context,
|
||||
$previous
|
||||
);
|
||||
}
|
||||
|
||||
public static function queryFailed(
|
||||
string $sql,
|
||||
?string $error = null,
|
||||
?\Throwable $previous = null
|
||||
): static {
|
||||
$context = ExceptionContext::forOperation('database.query', 'Database')
|
||||
->withData(['sql' => $sql, 'error' => $error])
|
||||
->withDebug(['query_length' => strlen($sql)]);
|
||||
|
||||
return static::create(
|
||||
ErrorCode::DB_QUERY_FAILED,
|
||||
"Query execution failed: $error",
|
||||
$context,
|
||||
$previous
|
||||
);
|
||||
}
|
||||
|
||||
public static function constraintViolation(
|
||||
string $constraint,
|
||||
?string $table = null,
|
||||
?array $data = null,
|
||||
?\Throwable $previous = null
|
||||
): static {
|
||||
$context = ExceptionContext::forOperation('database.constraint', 'Database')
|
||||
->withData([
|
||||
'dsn' => self::sanitizeDsn($dsn),
|
||||
'driver' => explode(':', $dsn)[0] ?? 'unknown'
|
||||
'constraint' => $constraint,
|
||||
'table' => $table,
|
||||
'violation_data' => $data,
|
||||
]);
|
||||
|
||||
return new self('Database connection failed', 0, $previous, $context);
|
||||
return static::create(
|
||||
ErrorCode::DB_CONSTRAINT_VIOLATION,
|
||||
"Database constraint violation: $constraint" . ($table ? " on table $table" : ''),
|
||||
$context,
|
||||
$previous
|
||||
);
|
||||
}
|
||||
|
||||
public static function queryFailed(string $query, array $params, \Throwable $previous): self
|
||||
{
|
||||
$context = ExceptionContext::forOperation('database.query', 'PDO')
|
||||
public static function transactionFailed(
|
||||
?string $details = null,
|
||||
?array $operations = null,
|
||||
?\Throwable $previous = null
|
||||
): static {
|
||||
$context = ExceptionContext::forOperation('database.transaction', 'Database')
|
||||
->withData(['details' => $details, 'operations' => $operations]);
|
||||
|
||||
return static::create(
|
||||
ErrorCode::DB_TRANSACTION_FAILED,
|
||||
"Transaction failed: $details",
|
||||
$context,
|
||||
$previous
|
||||
);
|
||||
}
|
||||
|
||||
public static function poolExhausted(
|
||||
int $maxConnections,
|
||||
int $currentConnections,
|
||||
?\Throwable $previous = null
|
||||
): static {
|
||||
$context = ExceptionContext::forOperation('database.pool', 'Database')
|
||||
->withData([
|
||||
'query' => $query,
|
||||
'parameters' => $params,
|
||||
'query_type' => self::detectQueryType($query)
|
||||
'max_connections' => $maxConnections,
|
||||
'current_connections' => $currentConnections,
|
||||
'usage_percentage' => round(($currentConnections / $maxConnections) * 100, 2),
|
||||
]);
|
||||
|
||||
return new self('Database query failed', 0, $previous, $context);
|
||||
return static::create(
|
||||
ErrorCode::DB_POOL_EXHAUSTED,
|
||||
"Connection pool exhausted ($currentConnections/$maxConnections)",
|
||||
$context,
|
||||
$previous
|
||||
);
|
||||
}
|
||||
|
||||
public static function transactionFailed(string $operation, \Throwable $previous): self
|
||||
{
|
||||
$context = ExceptionContext::forOperation('database.transaction', 'PDO')
|
||||
public static function timeout(
|
||||
float $timeoutSeconds,
|
||||
string $operation = 'query',
|
||||
?string $details = null,
|
||||
?\Throwable $previous = null
|
||||
): static {
|
||||
$context = ExceptionContext::forOperation("database.$operation", 'Database')
|
||||
->withData([
|
||||
'transaction_operation' => $operation
|
||||
'timeout_seconds' => $timeoutSeconds,
|
||||
'operation' => $operation,
|
||||
'details' => $details,
|
||||
]);
|
||||
|
||||
return new self("Database transaction failed: {$operation}", 0, $previous, $context);
|
||||
return static::create(
|
||||
ErrorCode::DB_TIMEOUT,
|
||||
"Database operation '$operation' timed out after {$timeoutSeconds}s",
|
||||
$context,
|
||||
$previous
|
||||
);
|
||||
}
|
||||
|
||||
private static function sanitizeDsn(string $dsn): string
|
||||
{
|
||||
return preg_replace('/password=[^;]+/', 'password=[REDACTED]', $dsn);
|
||||
}
|
||||
public static function migrationFailed(
|
||||
string $migrationName,
|
||||
?string $error = null,
|
||||
?string $version = null,
|
||||
?\Throwable $previous = null
|
||||
): static {
|
||||
$context = ExceptionContext::forOperation('database.migration', 'Database')
|
||||
->withData([
|
||||
'migration' => $migrationName,
|
||||
'version' => $version,
|
||||
'error' => $error,
|
||||
]);
|
||||
|
||||
private static function detectQueryType(string $query): string
|
||||
{
|
||||
$query = trim(strtoupper($query));
|
||||
return match (true) {
|
||||
str_starts_with($query, 'SELECT') => 'SELECT',
|
||||
str_starts_with($query, 'INSERT') => 'INSERT',
|
||||
str_starts_with($query, 'UPDATE') => 'UPDATE',
|
||||
str_starts_with($query, 'DELETE') => 'DELETE',
|
||||
str_starts_with($query, 'CREATE') => 'CREATE',
|
||||
str_starts_with($query, 'DROP') => 'DROP',
|
||||
str_starts_with($query, 'ALTER') => 'ALTER',
|
||||
default => 'UNKNOWN'
|
||||
};
|
||||
return static::create(
|
||||
ErrorCode::DB_MIGRATION_FAILED,
|
||||
"Migration '$migrationName' failed: $error",
|
||||
$context,
|
||||
$previous
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user