refactor: упростить комментарии в коде

- Удалить избыточные комментарии об обработке ошибок
- Убрать упоминания о старых проблемах (fallback, вместо throw)
- Сократить описания debug-опций
- Упростить комментарии о кэшировании
This commit is contained in:
kilyabin
2026-03-09 23:36:14 +04:00
parent 61669a840e
commit 0508333aeb
6 changed files with 41 additions and 48 deletions

View File

@@ -57,7 +57,7 @@ export async function getSchedule(groupID: number, groupName: string, wk?: numbe
dom = null
return scheduleResult
} catch(e) {
// Очищаем JSDOM даже в случае ошибки
// Очищаем JSDOM при ошибке
if (dom) {
dom.window.close()
}
@@ -118,7 +118,7 @@ export async function getSchedule(groupID: number, groupName: string, wk?: numbe
networkErrorMessage: networkError.message
})
} else if (networkError.code === 'DEPTH_ZERO_SELF_SIGNED_CERT' || networkError.message?.includes('self-signed certificate') || networkError.message?.includes('certificate')) {
// Ошибка SSL сертификата
// Обработка ошибки SSL сертификата
console.error(`SSL certificate error while fetching ${PROXY_URL}:`, {
code: networkError.code,
message: networkError.message,
@@ -144,7 +144,7 @@ export async function getSchedule(groupID: number, groupName: string, wk?: numbe
})
}
} else {
// Проверяем сообщение об ошибке на наличие упоминания сертификата
// Проверка на ошибку SSL сертификата по сообщению
if (errorObj.message?.includes('self-signed certificate') || errorObj.message?.includes('certificate')) {
const sslError = new Error(`В колледже что-то сломалось (проблема с сертификатом безопасности). Здесь я бессилен, проблема не на моей стороне.`)
logErrorToFile(sslError, {
@@ -207,7 +207,7 @@ export async function getTeacherSchedule(teacherID: number, teacherName: string,
dom = null
return scheduleResult
} catch(e) {
// Очищаем JSDOM даже в случае ошибки
// Очищаем JSDOM при ошибке
if (dom) {
dom.window.close()
}
@@ -268,7 +268,7 @@ export async function getTeacherSchedule(teacherID: number, teacherName: string,
networkErrorMessage: networkError.message
})
} else if (networkError.code === 'DEPTH_ZERO_SELF_SIGNED_CERT' || networkError.message?.includes('self-signed certificate') || networkError.message?.includes('certificate')) {
// Ошибка SSL сертификата
// Обработка ошибки SSL сертификата
console.error(`SSL certificate error while fetching ${PROXY_URL}:`, {
code: networkError.code,
message: networkError.message,
@@ -294,7 +294,7 @@ export async function getTeacherSchedule(teacherID: number, teacherName: string,
})
}
} else {
// Проверяем сообщение об ошибке на наличие упоминания сертификата
// Проверка на ошибку SSL сертификата по сообщению
if (errorObj.message?.includes('self-signed certificate') || errorObj.message?.includes('certificate')) {
const sslError = new Error(`В колледже что-то сломалось (проблема с сертификатом безопасности). Здесь я бессилен, проблема не на моей стороне.`)
logErrorToFile(sslError, {

View File

@@ -671,9 +671,9 @@ const parseLesson = (row: Element, isTeacherSchedule: boolean = false): Lesson |
}
}
// Для преподавателей может быть другая структура - проверяем наличие данных
// Для преподавателей может быть другая структура проверяем наличие данных
if (!cellText && !cellHTML) {
// Вместо ошибки, используем fallback
// Используем fallback для получения текста
const allText = row.textContent?.trim() || ''
if (allText && allText.length > 10) {
cellText = allText
@@ -1146,7 +1146,6 @@ export function parsePage(
throw new Error(`Table not found for ${groupName}. Found ${tables.length} tables on the page.`)
}
// К этому моменту table определен (иначе была бы ошибка выше)
const selectedTable = table!
logDebug('parsePage: selected table', { groupName, rows: selectedTable.querySelectorAll('tr').length })

View File

@@ -123,16 +123,16 @@ export default function HomePage(props: NextSerialized<PageProps>) {
}
const cachedSchedules = new Map<string, { lastFetched: Date, results: ScheduleResult }>()
const maxCacheDurationInMS = 1000 * 60 * 15 // 15 минут для нормального использования кэша
const fallbackCacheDurationInMS = 1000 * 60 * 60 * 24 // 24 часа для fallback кэша при ошибках парсинга
const maxCacheSize = 50 // Максимальное количество записей в кэше (только текущие недели)
const maxCacheDurationInMS = 1000 * 60 * 15 // 15 минут
const fallbackCacheDurationInMS = 1000 * 60 * 60 * 24 // 24 часа
const maxCacheSize = 50 // Максимальное количество записей в кэше
// Очистка старых записей из кэша
function cleanupCache() {
const now = Date.now()
const entriesToDelete: string[] = []
// Находим устаревшие записи (используем fallback TTL для сохранения кэша при ошибках)
// Находим устаревшие записи
for (const [key, value] of cachedSchedules.entries()) {
if (now - value.lastFetched.getTime() >= fallbackCacheDurationInMS) {
entriesToDelete.push(key)
@@ -164,7 +164,6 @@ export async function getServerSideProps(context: GetServerSidePropsContext<{ gr
: undefined
if (group && Object.hasOwn(groups, group) && group in groups) {
// Проверяем debug опции
const debug = settings.debug || {}
// Debug: принудительно показать ошибку
@@ -190,7 +189,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext<{ gr
}
}
// Debug: принудительно симулировать таймаут
// Debug: симулировать таймаут
if (debug.forceTimeout) {
const cacheAvailableFor = Array.from(cachedSchedules.entries())
.filter(([, v]) => v.lastFetched.getTime() + maxCacheDurationInMS > Date.now())
@@ -227,7 +226,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext<{ gr
const cacheKey = group // Ключ кэша - только группа (текущая неделя)
const cachedSchedule = useCache ? cachedSchedules.get(cacheKey) : undefined
// Debug: принудительно использовать кэш
// Debug: использовать кэш
if (debug.forceCache && cachedSchedule) {
scheduleResult = cachedSchedule.results
parsedAt = cachedSchedule.lastFetched
@@ -251,8 +250,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext<{ gr
cleanupCache()
}
} catch(e) {
// При таймауте или любой другой ошибке используем кэш, если он доступен (fallback кэш)
// Используем кэш независимо от возраста при ошибке парсинга
// При ошибке используем кэш, если он доступен
if (cachedSchedule) {
scheduleResult = cachedSchedule.results
parsedAt = cachedSchedule.lastFetched
@@ -266,7 +264,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext<{ gr
console.warn(`Schedule fetch error for group ${group}, using fallback cache from ${cachedSchedule.lastFetched.toISOString()} (${cacheAge} minutes old)`)
}
} else {
// Если кэша нет, возвращаем страницу с ошибкой вместо throw
// Если кэша нет, возвращаем страницу с ошибкой
const isTimeout = e instanceof ScheduleTimeoutError
const errorMessageObj = e instanceof Error ? e : new Error(String(e))
const isSSLError = errorMessageObj.message?.includes('колледже что-то сломалось') ||
@@ -278,7 +276,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext<{ gr
errorMessageObj.cause.message?.includes('self-signed certificate')
))
// Если ошибка уже содержит нужное сообщение, используем его напрямую
// Формируем сообщение об ошибке
let errorMessage: string
if (isTimeout) {
errorMessage = 'Превышено время ожидания ответа от сервера'
@@ -314,7 +312,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext<{ gr
}
}
// Debug: принудительно показать пустое расписание
// Debug: показать пустое расписание
if (debug.forceEmpty) {
scheduleResult = {
days: [],
@@ -344,9 +342,9 @@ export async function getServerSideProps(context: GetServerSidePropsContext<{ gr
const cacheAvailableFor = Array.from(cachedSchedules.entries())
.filter(([, v]) => v.lastFetched.getTime() + maxCacheDurationInMS > Date.now())
.map(([k]) => k.split('_')[0]) // Берем только группу из ключа кэша
.map(([k]) => k.split('_')[0])
// Debug: информация о кэше
// Информация о кэше (debug)
const cacheInfo = debug.showCacheInfo ? {
size: cachedSchedules.size,
entries: cachedSchedules.size

View File

@@ -202,7 +202,7 @@ export default function AdminPage({ groups: initialGroups, settings: initialSett
const loadSettingsList = () => loadData('/api/admin/settings', setSettings)
const handleUpdateSettings = async (newSettings: AppSettings) => {
// Сохраняем предыдущее состояние для отката при ошибке
// Сохраняем предыдущее состояние для отката
const previousSettings = settings
// Оптимистичное обновление UI
setSettings(newSettings)
@@ -218,18 +218,18 @@ export default function AdminPage({ groups: initialGroups, settings: initialSett
const data = await res.json()
if (res.ok && data.success) {
// Обновляем состояние из ответа сервера (для синхронизации)
// Обновляем состояние из ответа сервера
setSettings(data.settings)
showToast('Настройки успешно обновлены', 'success')
} else {
// Откатываем изменения при ошибке
// Откат изменений при ошибке
setSettings(previousSettings)
const errorMessage = data.error || 'Ошибка при обновлении настроек'
setError(errorMessage)
showToast(errorMessage, 'error')
}
} catch (err) {
// Откатываем изменения при ошибке
// Откат изменений при ошибке
setSettings(previousSettings)
const errorMessage = 'Ошибка соединения с сервером'
setError(errorMessage)

View File

@@ -112,16 +112,16 @@ export default function TeacherPage(props: NextSerialized<PageProps>) {
}
const cachedTeacherSchedules = new Map<string, { lastFetched: Date, results: ScheduleResult }>()
const maxCacheDurationInMS = 1000 * 60 * 15 // 15 минут для нормального использования кэша
const fallbackCacheDurationInMS = 1000 * 60 * 60 * 24 // 24 часа для fallback кэша при ошибках парсинга
const maxCacheSize = 50 // Максимальное количество записей в кэше (только текущие недели)
const maxCacheDurationInMS = 1000 * 60 * 15 // 15 минут
const fallbackCacheDurationInMS = 1000 * 60 * 60 * 24 // 24 часа
const maxCacheSize = 50 // Максимальное количество записей в кэше
// Очистка старых записей из кэша
function cleanupCache() {
const now = Date.now()
const entriesToDelete: string[] = []
// Находим устаревшие записи (используем fallback TTL для сохранения кэша при ошибках)
// Находим устаревшие записи
for (const [key, value] of cachedTeacherSchedules.entries()) {
if (now - value.lastFetched.getTime() >= fallbackCacheDurationInMS) {
entriesToDelete.push(key)
@@ -169,7 +169,6 @@ export async function getServerSideProps(context: GetServerSidePropsContext<{ te
}
}
// Проверяем debug опции
const debug = settings.debug || {}
// Debug: принудительно показать ошибку
@@ -195,7 +194,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext<{ te
}
}
// Debug: принудительно симулировать таймаут
// Debug: симулировать таймаут
if (debug.forceTimeout) {
const cacheAvailableFor = Array.from(cachedTeacherSchedules.entries())
.filter(([, v]) => v.lastFetched.getTime() + maxCacheDurationInMS > Date.now())
@@ -232,7 +231,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext<{ te
const cacheKey = `teacher_${teacherParseId}` // Ключ кэша для преподавателя
const cachedSchedule = useCache ? cachedTeacherSchedules.get(cacheKey) : undefined
// Debug: принудительно использовать кэш
// Debug: использовать кэш
if (debug.forceCache && cachedSchedule) {
scheduleResult = cachedSchedule.results
parsedAt = cachedSchedule.lastFetched
@@ -255,8 +254,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext<{ te
cleanupCache()
}
} catch(e) {
// При таймауте или любой другой ошибке используем кэш, если он доступен (fallback кэш)
// Используем кэш независимо от возраста при ошибке парсинга
// При ошибке используем кэш, если он доступен
if (cachedSchedule) {
scheduleResult = cachedSchedule.results
parsedAt = cachedSchedule.lastFetched
@@ -270,7 +268,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext<{ te
console.warn(`Schedule fetch error for teacher ${teacherInfo.name}, using fallback cache from ${cachedSchedule.lastFetched.toISOString()} (${cacheAge} minutes old)`)
}
} else {
// Если кэша нет, возвращаем страницу с ошибкой вместо throw
// Если кэша нет, возвращаем страницу с ошибкой
const isTimeout = e instanceof ScheduleTimeoutError
const errorMessageObj = e instanceof Error ? e : new Error(String(e))
const isSSLError = errorMessageObj.message?.includes('колледже что-то сломалось') ||
@@ -313,7 +311,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext<{ te
}
}
// Debug: принудительно показать пустое расписание
// Debug: показать пустое расписание
if (debug.forceEmpty) {
scheduleResult = {
days: [],
@@ -343,9 +341,9 @@ export async function getServerSideProps(context: GetServerSidePropsContext<{ te
const cacheAvailableFor = Array.from(cachedTeacherSchedules.entries())
.filter(([, v]) => v.lastFetched.getTime() + maxCacheDurationInMS > Date.now())
.map(([k]) => k.split('_')[1]) // Берем parseId из ключа кэша
.map(([k]) => k.split('_')[1])
// Debug: информация о кэше
// Информация о кэше (debug)
const cacheInfo = debug.showCacheInfo ? {
size: cachedTeacherSchedules.size,
entries: cachedTeacherSchedules.size

View File

@@ -381,8 +381,7 @@ export function getSettings(): AppSettings {
try {
const settings = JSON.parse(row.value) as Partial<AppSettings>
// Всегда добавляем дефолтные debug настройки (они не хранятся в БД)
// И добавляем отсутствующие поля для обратной совместимости
// Добавляем debug настройки и значения по умолчанию для обратной совместимости
return {
weekNavigationEnabled: settings.weekNavigationEnabled ?? false,
showAddGroupButton: settings.showAddGroupButton ?? true,
@@ -435,12 +434,11 @@ export function updateSettings(settings: AppSettings): void {
}
}
// Исключаем debug из настроек перед сохранением в БД
// Сохраняем настройки без debug (debug не хранится в БД)
const { debug, ...settingsWithoutDebug } = settings
const mergedSettings: AppSettings = {
...defaultSettings,
...settingsWithoutDebug
// debug намеренно не сохраняется в БД
}
database