diff --git a/backend/clients/myTischtennisClient.js b/backend/clients/myTischtennisClient.js index 79738726..bed32eca 100644 --- a/backend/clients/myTischtennisClient.js +++ b/backend/clients/myTischtennisClient.js @@ -520,10 +520,17 @@ class MyTischtennisClient { cookie }; } catch (error) { - console.error('[myTischtennisClient.playwright] Browser login failed:', error?.message || error); + const rawMessage = String(error?.message || error || 'Playwright-Login fehlgeschlagen'); + const isMissingBrowserExecutable = /Executable doesn't exist|download new browsers|playwright install/i.test(rawMessage); + const normalizedError = isMissingBrowserExecutable + ? 'Playwright-Browser ist auf dem Server nicht installiert. Bitte "npx playwright install chromium" ausführen.' + : rawMessage; + console.error('[myTischtennisClient.playwright] Browser login failed:', normalizedError); return { success: false, - error: error?.message || 'Playwright-Login fehlgeschlagen' + error: normalizedError, + requiresSetup: isMissingBrowserExecutable, + status: isMissingBrowserExecutable ? 503 : 400 }; } finally { if (context) { diff --git a/backend/services/myTischtennisService.js b/backend/services/myTischtennisService.js index 4a186ca4..c2bb171e 100644 --- a/backend/services/myTischtennisService.js +++ b/backend/services/myTischtennisService.js @@ -247,20 +247,25 @@ class MyTischtennisService { effectiveLoginResult = playwrightResult; } else { console.warn('[myTischtennisService.verifyLogin] Playwright-Fallback fehlgeschlagen:', playwrightResult.error); + const isSetupError = !!playwrightResult.requiresSetup || playwrightResult.status === 503; effectiveLoginResult = { success: false, error: playwrightResult.error || 'Playwright-Fallback fehlgeschlagen', - requiresCaptcha: true, - status: 400 + requiresCaptcha: !isSetupError, + status: isSetupError ? 503 : 400 }; } } catch (playwrightError) { console.warn('[myTischtennisService.verifyLogin] Playwright-Fallback Exception:', playwrightError?.message || playwrightError); + const rawMessage = String(playwrightError?.message || playwrightError || ''); + const isSetupError = /Executable doesn't exist|download new browsers|playwright install/i.test(rawMessage); effectiveLoginResult = { success: false, - error: `Playwright-Fallback Exception: ${playwrightError?.message || 'Unbekannter Fehler'}`, - requiresCaptcha: true, - status: 400 + error: isSetupError + ? 'Playwright-Browser ist auf dem Server nicht installiert. Bitte "npx playwright install chromium" ausführen.' + : `Playwright-Fallback Exception: ${playwrightError?.message || 'Unbekannter Fehler'}`, + requiresCaptcha: !isSetupError, + status: isSetupError ? 503 : 400 }; } } diff --git a/frontend/src/components/MyTischtennisDialog.vue b/frontend/src/components/MyTischtennisDialog.vue index eff82b8c..b1999923 100644 --- a/frontend/src/components/MyTischtennisDialog.vue +++ b/frontend/src/components/MyTischtennisDialog.vue @@ -170,9 +170,14 @@ export default { this.error = null; this.saving = true; try { - await apiClient.post('/mytischtennis/verify', { + const response = await apiClient.post('/mytischtennis/verify', { password: this.formData.password }); + if (response.status >= 400 || response?.data?.success === false) { + const requestError = new Error('myTischtennis verify failed'); + requestError.response = response; + throw requestError; + } this.$emit('logged-in'); } catch (error) { console.error('Fehler beim Login:', error); @@ -203,7 +208,12 @@ export default { payload.userPassword = this.formData.userPassword; } - await apiClient.post('/mytischtennis/account', payload); + const response = await apiClient.post('/mytischtennis/account', payload); + if (response.status >= 400 || response?.data?.success === false) { + const requestError = new Error('myTischtennis account save failed'); + requestError.response = response; + throw requestError; + } this.$emit('saved'); } catch (error) { console.error('Fehler beim Speichern:', error); diff --git a/frontend/src/views/MyTischtennisAccount.vue b/frontend/src/views/MyTischtennisAccount.vue index 10cc79fd..6347d5aa 100644 --- a/frontend/src/views/MyTischtennisAccount.vue +++ b/frontend/src/views/MyTischtennisAccount.vue @@ -233,7 +233,12 @@ export default { }; try { // 1-Klick-Re-Login: zuerst gespeicherte Session/Passwort serverseitig verwenden - await apiClient.post('/mytischtennis/verify', {}); + const response = await apiClient.post('/mytischtennis/verify', {}); + if (response.status >= 400 || response?.data?.success === false) { + const requestError = new Error('myTischtennis verify failed'); + requestError.response = response; + throw requestError; + } await this.loadAccount(); this.loginFeedback = { type: 'success',