**Änderungen:** - ✅ app.py: Hinzugefügt, um CSRF-Fehler zu behandeln - ✅ models.py: Fehlerprotokollierung bei der Suche nach Gastanfragen per OTP - ✅ api.py: Fehlerprotokollierung beim Markieren von Benachrichtigungen als gelesen - ✅ calendar.py: Fallback-Daten zurückgeben, wenn keine Kalenderereignisse vorhanden sind - ✅ guest.py: Status-Check-Seite für Gäste aktualisiert - ✅ hardware_integration.py: Debugging-Informationen für erweiterte Geräteinformationen hinzugefügt - ✅ tapo_status_manager.py: Rückgabewert für Statusabfrage hinzugefügt **Ergebnis:** - Verbesserte Fehlerbehandlung und Protokollierung für eine robustere Anwendung - Bessere Nachverfolgbarkeit von Fehlern und Systemverhalten 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
330 lines
12 KiB
JavaScript
330 lines
12 KiB
JavaScript
/**
|
|
* MYP Platform - Service Worker Debug & Test Utility
|
|
* Diagnose und Test-Tool für Service Worker Probleme
|
|
*/
|
|
|
|
class ServiceWorkerDebugger {
|
|
constructor() {
|
|
this.isDebugging = false;
|
|
this.testResults = [];
|
|
this.init();
|
|
}
|
|
|
|
init() {
|
|
console.log('[SW-Debug] Service Worker Debugger initialisiert');
|
|
|
|
// Automatische Diagnose beim Laden
|
|
if ('serviceWorker' in navigator) {
|
|
this.runDiagnostics();
|
|
} else {
|
|
console.error('[SW-Debug] Service Worker werden nicht unterstützt');
|
|
}
|
|
}
|
|
|
|
async runDiagnostics() {
|
|
console.log('[SW-Debug] Starte Service Worker Diagnose...');
|
|
|
|
try {
|
|
// 1. Service Worker Status prüfen
|
|
await this.checkServiceWorkerStatus();
|
|
|
|
// 2. Registrierte Service Worker auflisten
|
|
await this.listRegisteredServiceWorkers();
|
|
|
|
// 3. Cache-Status prüfen
|
|
await this.checkCacheStatus();
|
|
|
|
// 4. Test-Requests durchführen
|
|
await this.runTestRequests();
|
|
|
|
// 5. Ergebnisse ausgeben
|
|
this.outputResults();
|
|
|
|
} catch (error) {
|
|
console.error('[SW-Debug] Diagnose fehlgeschlagen:', error);
|
|
}
|
|
}
|
|
|
|
async checkServiceWorkerStatus() {
|
|
console.log('[SW-Debug] Prüfe Service Worker Status...');
|
|
|
|
try {
|
|
const registration = await navigator.serviceWorker.getRegistration();
|
|
|
|
if (registration) {
|
|
console.log('[SW-Debug] ✅ Service Worker registriert:', registration.scope);
|
|
|
|
if (registration.active) {
|
|
console.log('[SW-Debug] ✅ Service Worker aktiv:', registration.active.scriptURL);
|
|
this.testResults.push({
|
|
test: 'Service Worker Status',
|
|
status: 'PASS',
|
|
details: `Aktiv: ${registration.active.scriptURL}`
|
|
});
|
|
} else {
|
|
console.warn('[SW-Debug] ⚠️ Service Worker nicht aktiv');
|
|
this.testResults.push({
|
|
test: 'Service Worker Status',
|
|
status: 'WARN',
|
|
details: 'Service Worker registriert aber nicht aktiv'
|
|
});
|
|
}
|
|
|
|
if (registration.waiting) {
|
|
console.log('[SW-Debug] 🔄 Service Worker wartet auf Aktivierung');
|
|
}
|
|
|
|
if (registration.installing) {
|
|
console.log('[SW-Debug] 🔄 Service Worker wird installiert');
|
|
}
|
|
|
|
} else {
|
|
console.error('[SW-Debug] ❌ Kein Service Worker registriert');
|
|
this.testResults.push({
|
|
test: 'Service Worker Status',
|
|
status: 'FAIL',
|
|
details: 'Kein Service Worker registriert'
|
|
});
|
|
}
|
|
|
|
} catch (error) {
|
|
console.error('[SW-Debug] Fehler beim Prüfen des Service Worker Status:', error);
|
|
this.testResults.push({
|
|
test: 'Service Worker Status',
|
|
status: 'ERROR',
|
|
details: error.message
|
|
});
|
|
}
|
|
}
|
|
|
|
async listRegisteredServiceWorkers() {
|
|
console.log('[SW-Debug] Liste registrierte Service Worker...');
|
|
|
|
try {
|
|
const registrations = await navigator.serviceWorker.getRegistrations();
|
|
|
|
console.log(`[SW-Debug] ${registrations.length} Service Worker gefunden:`);
|
|
|
|
registrations.forEach((registration, index) => {
|
|
console.log(`[SW-Debug] ${index + 1}. Scope: ${registration.scope}`);
|
|
|
|
if (registration.active) {
|
|
console.log(`[SW-Debug] Aktiv: ${registration.active.scriptURL}`);
|
|
}
|
|
if (registration.waiting) {
|
|
console.log(`[SW-Debug] Wartend: ${registration.waiting.scriptURL}`);
|
|
}
|
|
if (registration.installing) {
|
|
console.log(`[SW-Debug] Installierend: ${registration.installing.scriptURL}`);
|
|
}
|
|
});
|
|
|
|
this.testResults.push({
|
|
test: 'Service Worker Registrierungen',
|
|
status: registrations.length > 0 ? 'PASS' : 'WARN',
|
|
details: `${registrations.length} Service Worker registriert`
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error('[SW-Debug] Fehler beim Auflisten der Service Worker:', error);
|
|
this.testResults.push({
|
|
test: 'Service Worker Registrierungen',
|
|
status: 'ERROR',
|
|
details: error.message
|
|
});
|
|
}
|
|
}
|
|
|
|
async checkCacheStatus() {
|
|
console.log('[SW-Debug] Prüfe Cache Status...');
|
|
|
|
try {
|
|
const cacheNames = await caches.keys();
|
|
console.log(`[SW-Debug] ${cacheNames.length} Caches gefunden:`);
|
|
|
|
let totalEntries = 0;
|
|
|
|
for (const cacheName of cacheNames) {
|
|
const cache = await caches.open(cacheName);
|
|
const keys = await cache.keys();
|
|
console.log(`[SW-Debug] - ${cacheName}: ${keys.length} Einträge`);
|
|
totalEntries += keys.length;
|
|
}
|
|
|
|
this.testResults.push({
|
|
test: 'Cache Status',
|
|
status: 'PASS',
|
|
details: `${cacheNames.length} Caches mit ${totalEntries} Einträgen`
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error('[SW-Debug] Fehler beim Prüfen des Cache Status:', error);
|
|
this.testResults.push({
|
|
test: 'Cache Status',
|
|
status: 'ERROR',
|
|
details: error.message
|
|
});
|
|
}
|
|
}
|
|
|
|
async runTestRequests() {
|
|
console.log('[SW-Debug] Führe Test-Requests durch...');
|
|
|
|
const testUrls = [
|
|
'/static/css/tailwind.min.css',
|
|
'/static/js/ui-components.js',
|
|
'/api/dashboard',
|
|
'/dashboard'
|
|
];
|
|
|
|
for (const url of testUrls) {
|
|
try {
|
|
console.log(`[SW-Debug] Teste Request: ${url}`);
|
|
|
|
const startTime = performance.now();
|
|
const response = await fetch(url);
|
|
const endTime = performance.now();
|
|
|
|
const responseTime = Math.round(endTime - startTime);
|
|
const servedBy = response.headers.get('X-Served-By') || 'Network';
|
|
|
|
if (response.ok) {
|
|
console.log(`[SW-Debug] ✅ ${url} - ${response.status} (${responseTime}ms, ${servedBy})`);
|
|
this.testResults.push({
|
|
test: `Request Test: ${url}`,
|
|
status: 'PASS',
|
|
details: `${response.status} - ${responseTime}ms - ${servedBy}`
|
|
});
|
|
} else {
|
|
console.warn(`[SW-Debug] ⚠️ ${url} - ${response.status} ${response.statusText}`);
|
|
this.testResults.push({
|
|
test: `Request Test: ${url}`,
|
|
status: 'WARN',
|
|
details: `${response.status} ${response.statusText}`
|
|
});
|
|
}
|
|
|
|
} catch (error) {
|
|
console.error(`[SW-Debug] ❌ ${url} - Fehler:`, error);
|
|
this.testResults.push({
|
|
test: `Request Test: ${url}`,
|
|
status: 'ERROR',
|
|
details: error.message
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
outputResults() {
|
|
console.log('[SW-Debug] === DIAGNOSE-ERGEBNISSE ===');
|
|
|
|
const passed = this.testResults.filter(r => r.status === 'PASS').length;
|
|
const warned = this.testResults.filter(r => r.status === 'WARN').length;
|
|
const failed = this.testResults.filter(r => r.status === 'FAIL').length;
|
|
const errors = this.testResults.filter(r => r.status === 'ERROR').length;
|
|
|
|
console.log(`[SW-Debug] Gesamt: ${this.testResults.length} Tests`);
|
|
console.log(`[SW-Debug] ✅ Erfolgreich: ${passed}`);
|
|
console.log(`[SW-Debug] ⚠️ Warnungen: ${warned}`);
|
|
console.log(`[SW-Debug] ❌ Fehlgeschlagen: ${failed}`);
|
|
console.log(`[SW-Debug] 💥 Fehler: ${errors}`);
|
|
|
|
// Detaillierte Ergebnisse
|
|
this.testResults.forEach(result => {
|
|
const icon = this.getStatusIcon(result.status);
|
|
console.log(`[SW-Debug] ${icon} ${result.test}: ${result.details}`);
|
|
});
|
|
|
|
// Empfehlungen ausgeben
|
|
this.outputRecommendations();
|
|
}
|
|
|
|
getStatusIcon(status) {
|
|
switch (status) {
|
|
case 'PASS': return '✅';
|
|
case 'WARN': return '⚠️';
|
|
case 'FAIL': return '❌';
|
|
case 'ERROR': return '💥';
|
|
default: return '❓';
|
|
}
|
|
}
|
|
|
|
outputRecommendations() {
|
|
console.log('[SW-Debug] === EMPFEHLUNGEN ===');
|
|
|
|
const hasErrors = this.testResults.some(r => r.status === 'ERROR' || r.status === 'FAIL');
|
|
|
|
if (hasErrors) {
|
|
console.log('[SW-Debug] 🔧 Probleme erkannt:');
|
|
console.log('[SW-Debug] - Service Worker Cache leeren: await caches.keys().then(names => Promise.all(names.map(name => caches.delete(name))))');
|
|
console.log('[SW-Debug] - Service Worker neu registrieren: navigator.serviceWorker.getRegistrations().then(regs => regs.forEach(reg => reg.unregister()))');
|
|
console.log('[SW-Debug] - Browser-Cache leeren und Seite neu laden');
|
|
} else {
|
|
console.log('[SW-Debug] ✅ Service Worker funktioniert korrekt');
|
|
}
|
|
}
|
|
|
|
// Utility-Methoden für manuelle Tests
|
|
async clearAllCaches() {
|
|
console.log('[SW-Debug] Lösche alle Caches...');
|
|
try {
|
|
const cacheNames = await caches.keys();
|
|
await Promise.all(cacheNames.map(name => caches.delete(name)));
|
|
console.log('[SW-Debug] ✅ Alle Caches gelöscht');
|
|
} catch (error) {
|
|
console.error('[SW-Debug] Fehler beim Löschen der Caches:', error);
|
|
}
|
|
}
|
|
|
|
async unregisterAllServiceWorkers() {
|
|
console.log('[SW-Debug] Deregistriere alle Service Worker...');
|
|
try {
|
|
const registrations = await navigator.serviceWorker.getRegistrations();
|
|
await Promise.all(registrations.map(reg => reg.unregister()));
|
|
console.log('[SW-Debug] ✅ Alle Service Worker deregistriert');
|
|
} catch (error) {
|
|
console.error('[SW-Debug] Fehler beim Deregistrieren der Service Worker:', error);
|
|
}
|
|
}
|
|
|
|
async forceServiceWorkerUpdate() {
|
|
console.log('[SW-Debug] Erzwinge Service Worker Update...');
|
|
try {
|
|
const registration = await navigator.serviceWorker.getRegistration();
|
|
if (registration) {
|
|
await registration.update();
|
|
console.log('[SW-Debug] ✅ Service Worker Update angefordert');
|
|
} else {
|
|
console.warn('[SW-Debug] Kein Service Worker zum Aktualisieren gefunden');
|
|
}
|
|
} catch (error) {
|
|
console.error('[SW-Debug] Fehler beim Service Worker Update:', error);
|
|
}
|
|
}
|
|
|
|
// Event-Listener für Service Worker Events
|
|
setupEventListeners() {
|
|
if ('serviceWorker' in navigator) {
|
|
navigator.serviceWorker.addEventListener('controllerchange', () => {
|
|
console.log('[SW-Debug] 🔄 Service Worker Controller hat gewechselt');
|
|
});
|
|
|
|
navigator.serviceWorker.addEventListener('message', (event) => {
|
|
console.log('[SW-Debug] 📨 Message vom Service Worker:', event.data);
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
// Globale Instanz für Debugging
|
|
window.swDebugger = new ServiceWorkerDebugger();
|
|
|
|
// Utility-Funktionen für die Konsole
|
|
window.swDebug = {
|
|
run: () => window.swDebugger.runDiagnostics(),
|
|
clearCaches: () => window.swDebugger.clearAllCaches(),
|
|
unregisterAll: () => window.swDebugger.unregisterAllServiceWorkers(),
|
|
forceUpdate: () => window.swDebugger.forceServiceWorkerUpdate()
|
|
};
|
|
|
|
console.log('[SW-Debug] Service Worker Debugger geladen. Verwende swDebug.run() für Diagnose.');
|