feat(clickTtTournamentRegistrationService): enhance error handling and diagnostics for tournament registration
- Added detailed diagnostics to capture page content and URLs during registration failures, improving error reporting. - Implemented a function to build a debug HTML path for saving page content, aiding in troubleshooting. - Updated error handling to include relevant diagnostic information in error messages, enhancing clarity for users.
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
import { chromium } from 'playwright';
|
||||
import { mkdir, writeFile } from 'fs/promises';
|
||||
import path from 'path';
|
||||
import Club from '../models/Club.js';
|
||||
import ClickTtAccount from '../models/ClickTtAccount.js';
|
||||
import OfficialTournament from '../models/OfficialTournament.js';
|
||||
@@ -58,6 +60,15 @@ function parseDmyRange(value) {
|
||||
};
|
||||
}
|
||||
|
||||
function buildDebugHtmlPath() {
|
||||
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
||||
return path.join(process.cwd(), 'tmp', `clicktt-tournament-debug-${timestamp}.html`);
|
||||
}
|
||||
|
||||
function sanitizePageText(text) {
|
||||
return String(text || '').replace(/\s+/g, ' ').trim().slice(0, 500);
|
||||
}
|
||||
|
||||
class ClickTtTournamentRegistrationService {
|
||||
async autoRegisterPendingParticipants({ userToken, userId, clubId, tournamentId }) {
|
||||
await checkAccess(userToken, clubId);
|
||||
@@ -134,6 +145,7 @@ class ClickTtTournamentRegistrationService {
|
||||
let context = null;
|
||||
let page = null;
|
||||
const trace = [];
|
||||
let resultsPageUrl = null;
|
||||
|
||||
try {
|
||||
browser = await chromium.launch({
|
||||
@@ -154,7 +166,7 @@ class ClickTtTournamentRegistrationService {
|
||||
await clickTtPlayerRegistrationService._selectClubContext(page, associationMemberNumber, trace);
|
||||
await this._openTournamentSearch(page, trace);
|
||||
await this._filterTournamentSearch(page, tournament, trace);
|
||||
const resultsPageUrl = page.url();
|
||||
resultsPageUrl = page.url();
|
||||
|
||||
const processedCompetitions = [];
|
||||
for (const group of competitionGroups) {
|
||||
@@ -197,9 +209,49 @@ class ClickTtTournamentRegistrationService {
|
||||
competitions: processedCompetitions
|
||||
};
|
||||
} catch (error) {
|
||||
throw error instanceof HttpError
|
||||
? error
|
||||
: new HttpError(`Click-TT-Turnieranmeldung fehlgeschlagen: ${error.message || error}`, 500);
|
||||
const diagnostics = {
|
||||
url: null,
|
||||
text: null,
|
||||
htmlPath: null,
|
||||
resultsPageUrl
|
||||
};
|
||||
|
||||
try {
|
||||
const html = await page?.content?.();
|
||||
const htmlPath = html ? buildDebugHtmlPath() : null;
|
||||
if (html && htmlPath) {
|
||||
await mkdir(path.dirname(htmlPath), { recursive: true });
|
||||
await writeFile(htmlPath, html, 'utf8');
|
||||
diagnostics.htmlPath = htmlPath;
|
||||
}
|
||||
} catch (_err) {
|
||||
// keep partial diagnostics
|
||||
}
|
||||
|
||||
try {
|
||||
diagnostics.url = page?.url?.() || null;
|
||||
} catch (_err) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
try {
|
||||
diagnostics.text = sanitizePageText(await page?.locator?.('body')?.innerText?.());
|
||||
} catch (_err) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
const baseMessage = error instanceof HttpError
|
||||
? error.message
|
||||
: `Click-TT-Turnieranmeldung fehlgeschlagen: ${error.message || error}`;
|
||||
const wrappedError = new HttpError(
|
||||
`${baseMessage}${diagnostics.url ? ` (Seite: ${diagnostics.url})` : ''}${diagnostics.htmlPath ? ` (HTML: ${diagnostics.htmlPath})` : ''}${diagnostics.text ? ` - ${diagnostics.text}` : ''}`,
|
||||
error.statusCode || error.status || 500
|
||||
);
|
||||
wrappedError.htmlPath = diagnostics.htmlPath || null;
|
||||
wrappedError.details = {
|
||||
resultsPageUrl: diagnostics.resultsPageUrl || null
|
||||
};
|
||||
throw wrappedError;
|
||||
} finally {
|
||||
if (context) {
|
||||
try { await context.close(); } catch (_err) {}
|
||||
|
||||
Reference in New Issue
Block a user