refactor: enhance error reporting and logging, add installer script

- Update `LogReporter` and `Reporter` interface to handle `Throwable` instead of `string`
- Simplify initializer discovery message in `ClassNotInstantiable` exceptions
- Remove unnecessary debug logs in `HttpRouter`
- Add `scripts/install-aliases.sh` for setting up console aliases
- Add minimal `console` script for Docker execution
This commit is contained in:
2025-11-03 14:21:10 +01:00
parent 1109b0f94b
commit bc7cdf5fed
7 changed files with 200 additions and 11 deletions

2
console Normal file
View File

@@ -0,0 +1,2 @@
#!/usr/bin/env bash
docker exec -it php php console.php "$@"

View File

@@ -0,0 +1,171 @@
#!/usr/bin/env bash
set -euo pipefail
# ────────────────────────────────────────────────────────────────────────────────
# Config (kannst du beim Aufruf per ENV überschreiben)
# PROJECT_CONTAINER: Name des PHP-Containers (Compose-Service). Default: php
# CONSOLE_PATH: Pfad zur console.php im Container. Default: /var/www/html/console.php
# LOCAL_CONSOLE: Pfad zur lokalen console.php. Default: ./console.php
# ────────────────────────────────────────────────────────────────────────────────
PROJECT_CONTAINER="${PROJECT_CONTAINER:-php}"
CONSOLE_PATH="${CONSOLE_PATH:-/var/www/html/console.php}"
LOCAL_CONSOLE="${LOCAL_CONSOLE:-./console.php}"
MARKER_START="# >>> PROJECT CONSOLE ALIASES >>>"
MARKER_END="# <<< PROJECT CONSOLE ALIASES <<<"
detect_shell_rc_file() {
# Bevorzugt Bash-Setup mit ~/.bash_aliases (Debian/WSL-Standard),
# sonst Zsh (~/.zshrc). Fällt zurück auf ~/.bashrc.
if [[ -n "${ZSH_VERSION-}" ]] || [[ "${SHELL:-}" == *"zsh"* ]] || pgrep -fa zsh >/dev/null 2>&1; then
echo "$HOME/.zshrc"
elif [[ -n "${BASH_VERSION-}" ]] || [[ "${SHELL:-}" == *"bash"* ]] || pgrep -fa bash >/dev/null 2>&1; then
# Nutze ~/.bash_aliases falls .bashrc sie lädt, sonst ~/.bashrc
if [[ -f "$HOME/.bashrc" ]] && grep -qs "^\s*if\s\+\[ -f ~/.bash_aliases \]" "$HOME/.bashrc"; then
echo "$HOME/.bash_aliases"
else
echo "$HOME/.bashrc"
fi
else
# Fallback
echo "$HOME/.bashrc"
fi
}
ensure_bashrc_sources_aliases() {
# Stellt sicher, dass ~/.bashrc ~/.bash_aliases lädt (Debian-Standard meistens schon vorhanden)
local bashrc="$HOME/.bashrc"
if [[ ! -f "$bashrc" ]]; then return 0; fi
if grep -qs "~/.bash_aliases" "$bashrc"; then return 0; fi
{
echo
echo "# Load user aliases if present"
echo 'if [ -f ~/.bash_aliases ]; then'
echo ' . ~/.bash_aliases'
echo 'fi'
} >> "$bashrc"
}
install_block() {
local rc_file="$1"
mkdir -p "$(dirname "$rc_file")"
touch "$rc_file"
# Vorhandenen Block entfernen
sed -i "/$MARKER_START/,/$MARKER_END/d" "$rc_file" || true
# Block hinzufügen (Single-quoted EOF, damit Variablen nicht vom Installer expandiert werden)
cat >> "$rc_file" <<'EOF'
# >>> PROJECT CONSOLE ALIASES >>>
# Funktion "console": führt deine PHP-Konsole im Docker-Container *oder* lokal aus.
# - Erkennt "docker compose" vs "docker-compose"
# - Sucht optional ein docker-compose.yml im aktuellen/vererbten Verzeichnisbaum
# - Übergibt alle Argumente transparent weiter
console() {
# Defaults (können per ENV überschrieben werden)
local PROJECT_CONTAINER="${PROJECT_CONTAINER:-php}"
local CONSOLE_PATH="${CONSOLE_PATH:-/var/www/html/console.php}"
local LOCAL_CONSOLE="${LOCAL_CONSOLE:-./console.php}"
# Finde Compose-Befehl
local COMPOSE_BIN="docker compose"
if ! docker compose version >/dev/null 2>&1; then
if command -v docker-compose >/dev/null 2>&1; then
COMPOSE_BIN="docker-compose"
fi
fi
# Suche ein Compose-Projekt nach oben (max 10 Ebenen), damit "console" auch in Subfolders funktioniert
find_compose_dir() {
local d="$PWD"
local i=0
while [[ "$d" != "/" && $i -lt 10 ]]; do
if [[ -f "$d/docker-compose.yml" || -f "$d/compose.yml" ]]; then
echo "$d"
return 0
fi
d="$(dirname "$d")"
i=$((i+1))
done
return 1
}
local compose_dir
if compose_dir="$(find_compose_dir)"; then
# Prüfe, ob der gewünschte Service läuft
local container_id
if container_id=$(
(cd "$compose_dir" && $COMPOSE_BIN ps -q "$PROJECT_CONTAINER" 2>/dev/null) || true
); then
if [[ -n "$container_id" ]]; then
docker exec -it "$container_id" php "$CONSOLE_PATH" "$@"
return $?
fi
fi
fi
# Fallback: Lokal ausführen
if [[ -f "$LOCAL_CONSOLE" ]]; then
php "$LOCAL_CONSOLE" "$@"
else
# Letzter Fallback: direkter Aufruf, falls global im PATH
php console.php "$@"
fi
}
# <<< PROJECT CONSOLE ALIASES <<<
EOF
}
uninstall_block() {
local rc_file="$1"
[[ -f "$rc_file" ]] || return 0
sed -i "/$MARKER_START/,/$MARKER_END/d" "$rc_file" || true
}
usage() {
cat <<USAGE
Installiert eine 'console' Shell-Funktion in dein Shell-RC (Bash/Zsh),
die automatisch entweder im Docker-Container oder lokal deine console.php ausführt.
Verwendung:
$(basename "$0") [--uninstall]
Umgebungsvariablen (optional):
PROJECT_CONTAINER Compose-Service-Name für PHP (Default: php)
CONSOLE_PATH Pfad zur console.php IM Container (Default: /var/www/html/console.php)
LOCAL_CONSOLE Pfad zur lokalen console.php (Default: ./console.php)
USAGE
}
main() {
if [[ "${1-}" == "-h" || "${1-}" == "--help" ]]; then
usage; exit 0
fi
local rc_file
rc_file="$(detect_shell_rc_file)"
if [[ "${1-}" == "--uninstall" ]]; then
uninstall_block "$rc_file"
echo "🗑️ Entfernt: Block aus $rc_file"
echo "➡️ Bitte lade deine Shell neu: source \"$rc_file\" (oder starte ein neues Terminal)"
exit 0
fi
# Bash-spezifisch: sicherstellen, dass ~/.bash_aliases geladen wird
if [[ "$rc_file" == "$HOME/.bash_aliases" ]]; then
ensure_bashrc_sources_aliases
fi
install_block "$rc_file"
echo "✅ Installiert in: $rc_file"
echo " Container-Service: $PROJECT_CONTAINER"
echo " Console im Container: $CONSOLE_PATH"
echo " Console lokal: $LOCAL_CONSOLE"
echo
echo "➡️ Jetzt Shell neu laden: source \"$rc_file\""
echo "➡️ Test: console list oder console migrate --env=staging"
}
main "$@"

View File

@@ -65,8 +65,16 @@ final class ClassNotInstantiable extends ContainerException
}
if (!empty($this->discoveredInitializers)) {
$initializers = [];
foreach($this->discoveredInitializers as $initializer) {
$array = explode('\\', $initializer);
$initializers[] = end($array);
}
$message .= "Discovered initializers (" . count($this->discoveredInitializers) . "): " .
implode(', ', $this->discoveredInitializers) . "\n";
implode(', ', $initializers) . "\n";
} else {
$message .= "No initializers discovered in DiscoveryRegistry.\n";
}

View File

@@ -15,7 +15,7 @@ final readonly class ErrorKernel
{
$log = new LogReporter();
$log->report($e->getMessage());
$log->report($e);
var_dump((string)$e);

View File

@@ -5,8 +5,22 @@ namespace App\Framework\ExceptionHandling\Reporter;
final class LogReporter implements Reporter
{
public function report(string $message): void
public function report(\Throwable $e): void
{
echo ("[log] " . $message);
echo "<pre>\n";
echo $e->getMessage();
echo "\n";
echo $e->getFile().':'.$e->getLine();
echo "\n";
echo "\n";
echo $e->getTraceAsString();
echo "</pre>\n";
}
}

View File

@@ -4,5 +4,5 @@ namespace App\Framework\ExceptionHandling\Reporter;
interface Reporter
{
public function report(string $message): void;
public function report(\Throwable $e): void;
}

View File

@@ -28,17 +28,11 @@ final readonly class HttpRouter implements Router
$appUrl = $this->environment->getString(EnvKey::APP_URL);
error_log('APPURL: ' . $appUrl);
error_log('HOST: ' . $host);
$pos = stripos($appUrl, '://');
if($pos !== false) {
$appUrl = substr($appUrl,$pos + 3);
}
error_log('APPURL CLEAN: ' . $appUrl);
$subdomain = Subdomain::tryFromHost($host, $appUrl) ?? '';
$subdomain = (string)$subdomain;