fehlerseiten
This commit is contained in:
@@ -34,12 +34,12 @@ $validActions = ['list', 'edit', 'save', 'ports', 'delete'];
|
|||||||
|
|
||||||
// Prüfen auf gültige Werte
|
// Prüfen auf gültige Werte
|
||||||
if (!in_array($module, $validModules)) {
|
if (!in_array($module, $validModules)) {
|
||||||
// TODO: Fehlerseite anzeigen
|
// TODO: Fehlerseite anzeigen, nutze renderClientError(...)
|
||||||
die('Ungültiges Modul');
|
die('Ungültiges Modul');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!in_array($action, $validActions)) {
|
if (!in_array($action, $validActions)) {
|
||||||
// TODO: Fehlerseite anzeigen
|
// TODO: Fehlerseite anzeigen, nutze renderClientError(...)
|
||||||
die('Ungültige Aktion');
|
die('Ungültige Aktion');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ $modulePath = __DIR__ . "/modules/$module/$action.php";
|
|||||||
if (file_exists($modulePath)) {
|
if (file_exists($modulePath)) {
|
||||||
require_once $modulePath;
|
require_once $modulePath;
|
||||||
} else {
|
} else {
|
||||||
// TODO: Fehlerseite oder 404
|
// TODO: Fehlerseite oder 404, nutze renderClientError(...)
|
||||||
if ($action !== 'save') {
|
if ($action !== 'save') {
|
||||||
echo "<p>Die Seite existiert noch nicht.</p>".$modulePath;
|
echo "<p>Die Seite existiert noch nicht.</p>".$modulePath;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -206,6 +206,93 @@ function dd($value): void
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zeigt eine sauber gestaltete Fehlerseite für 40x-Status-Codes mit Erklärung.
|
||||||
|
*
|
||||||
|
* @param int $statusCode Client-Error-Status (400–499)
|
||||||
|
* @param string $explanation Optionale Zusatzinfo zur Problemursache
|
||||||
|
* @param string[] $tips Handlungsvorschläge für Benutzer (optional)
|
||||||
|
*/
|
||||||
|
function renderClientError(int $statusCode, string $explanation = '', array $tips = []): void
|
||||||
|
{
|
||||||
|
if ($statusCode < 400 || $statusCode >= 500) {
|
||||||
|
$statusCode = 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
$reasons = [
|
||||||
|
400 => 'Ungültige Anfrage',
|
||||||
|
401 => 'Nicht authentifiziert',
|
||||||
|
403 => 'Zugriff verweigert',
|
||||||
|
404 => 'Seite nicht gefunden',
|
||||||
|
405 => 'Methode nicht erlaubt',
|
||||||
|
408 => 'Anfrage abgelaufen',
|
||||||
|
429 => 'Zu viele Anfragen',
|
||||||
|
];
|
||||||
|
|
||||||
|
$reason = $reasons[$statusCode] ?? 'Clientseitiger Fehler';
|
||||||
|
$defaultExplanation = match ($statusCode) {
|
||||||
|
400 => 'Die Anfrage konnte aufgrund fehlender oder falscher Daten nicht verstanden werden.',
|
||||||
|
401 => 'Bitte melden Sie sich an oder verwenden gültige Zugangsdaten.',
|
||||||
|
403 => 'Sie besitzen keinen Zugriff auf diesen Bereich.',
|
||||||
|
404 => 'Die angeforderte Ressource existiert nicht oder wurde verschoben.',
|
||||||
|
405 => 'Diese Aktion ist auf dem Server nicht erlaubt.',
|
||||||
|
408 => 'Die Anfrage hat zu lange gedauert; bitte erneut versuchen.',
|
||||||
|
429 => 'Sie senden zu viele Anfragen in kurzer Zeit.',
|
||||||
|
default => 'Die Anfrage kann nicht verarbeitet werden; überprüfen Sie die Eingaben.',
|
||||||
|
};
|
||||||
|
|
||||||
|
$message = $explanation !== '' ? $explanation : $defaultExplanation;
|
||||||
|
|
||||||
|
http_response_code($statusCode);
|
||||||
|
|
||||||
|
$css = <<<CSS
|
||||||
|
body { font-family: 'Segoe UI', system-ui, sans-serif; margin: 0; background: #0b1220; color: #e0e7ff; }
|
||||||
|
.page { min-height: 100vh; display: flex; justify-content: center; align-items: center; padding: 2rem; }
|
||||||
|
.card { max-width: 640px; background: linear-gradient(145deg, #16213d, #0d0f1f); border: 1px solid rgba(224,231,255,0.2); border-radius: 1rem; box-shadow: 0 20px 45px rgba(0,0,0,0.45); padding: 2rem; }
|
||||||
|
h1 { margin: 0 0 0.5rem; font-size: clamp(2.5rem, 3vw, 3.5rem); }
|
||||||
|
p { margin: 0 0 1rem; line-height: 1.6; color: rgba(224,231,255,0.9); }
|
||||||
|
.badge { display: inline-flex; align-items: center; padding: 0.25rem 0.75rem; border-radius: 999px; font-size: 0.85rem; background: rgba(255,255,255,0.08); color: #a5b4fc; margin-bottom: 1rem; }
|
||||||
|
ul { margin: 1rem 0 0; padding-left: 1.25rem; color: rgba(224,231,255,0.85); }
|
||||||
|
a { color: #7dd3fc; text-decoration: none; }
|
||||||
|
a:hover { text-decoration: underline; }
|
||||||
|
CSS;
|
||||||
|
|
||||||
|
$rendered = strtr(<<<'HTML'
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||||
|
<title>Fehler {{code}}</title>
|
||||||
|
<style>{{css}}</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="page">
|
||||||
|
<section class="card">
|
||||||
|
<div class="badge">{{status}}</div>
|
||||||
|
<h1>{{code}} · {{reason}}</h1>
|
||||||
|
<p>{{message}}</p>
|
||||||
|
{{tips}}
|
||||||
|
<p>Zurück zur Startseite: <a href="/">Dashboard</a></p>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
HTML, [
|
||||||
|
'{{code}}' => e((string)$statusCode),
|
||||||
|
'{{reason}}' => e($reason),
|
||||||
|
'{{status}}' => e(sprintf('%d Fehler', $statusCode)),
|
||||||
|
'{{message}}' => e($message),
|
||||||
|
'{{css}}' => $css,
|
||||||
|
'{{tips}}' => count($tips) === 0
|
||||||
|
? ''
|
||||||
|
: '<ul>' . implode('', array_map(fn($tip) => '<li>' . e($tip) . '</li>', $tips)) . '</ul>',
|
||||||
|
]);
|
||||||
|
|
||||||
|
echo $rendered;
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
/* =========================
|
/* =========================
|
||||||
* Sonstiges
|
* Sonstiges
|
||||||
* ========================= */
|
* ========================= */
|
||||||
|
|||||||
Reference in New Issue
Block a user