Spaces:
Sleeping
Sleeping
| """ | |
| Console Collector - перехват console.log/error/warn | |
| """ | |
| from typing import Dict, List | |
| from .base import BaseCollector | |
| class ConsoleCollector(BaseCollector): | |
| """ | |
| Перехватывает console.log, console.error, console.warn. | |
| Полезно для: | |
| - Отладки JavaScript ошибок | |
| - Понимания что происходит в AWS скриптах | |
| - Обнаружения проблем с fingerprint | |
| """ | |
| name = "console" | |
| def __init__(self, session): | |
| super().__init__(session) | |
| self._logs = [] | |
| def inject(self): | |
| """Инжектит перехватчик console""" | |
| if not self.page: | |
| return | |
| interceptor_js = ''' | |
| (function() { | |
| if (window.__consoleInterceptorInstalled) return; | |
| window.__consoleInterceptorInstalled = true; | |
| window.__consoleLogs = []; | |
| const maxLogs = 500; | |
| function captureLog(type, args) { | |
| const entry = { | |
| timestamp: Date.now(), | |
| type: type, | |
| message: args.map(arg => { | |
| try { | |
| if (typeof arg === 'object') { | |
| return JSON.stringify(arg).substring(0, 1000); | |
| } | |
| return String(arg).substring(0, 1000); | |
| } catch(e) { | |
| return '[Unable to stringify]'; | |
| } | |
| }).join(' ') | |
| }; | |
| window.__consoleLogs.push(entry); | |
| // Ограничиваем размер | |
| if (window.__consoleLogs.length > maxLogs) { | |
| window.__consoleLogs = window.__consoleLogs.slice(-maxLogs); | |
| } | |
| } | |
| const origLog = console.log; | |
| const origError = console.error; | |
| const origWarn = console.warn; | |
| const origInfo = console.info; | |
| const origDebug = console.debug; | |
| console.log = function(...args) { | |
| captureLog('log', args); | |
| return origLog.apply(console, args); | |
| }; | |
| console.error = function(...args) { | |
| captureLog('error', args); | |
| return origError.apply(console, args); | |
| }; | |
| console.warn = function(...args) { | |
| captureLog('warn', args); | |
| return origWarn.apply(console, args); | |
| }; | |
| console.info = function(...args) { | |
| captureLog('info', args); | |
| return origInfo.apply(console, args); | |
| }; | |
| console.debug = function(...args) { | |
| captureLog('debug', args); | |
| return origDebug.apply(console, args); | |
| }; | |
| // Перехватываем глобальные ошибки | |
| window.addEventListener('error', function(event) { | |
| captureLog('uncaught_error', [ | |
| event.message, | |
| 'at', event.filename, | |
| 'line', event.lineno, | |
| 'col', event.colno | |
| ]); | |
| }); | |
| window.addEventListener('unhandledrejection', function(event) { | |
| captureLog('unhandled_rejection', [ | |
| event.reason ? (event.reason.message || String(event.reason)) : 'Unknown rejection' | |
| ]); | |
| }); | |
| console.log('[ConsoleCollector] Interceptor installed'); | |
| })(); | |
| ''' | |
| try: | |
| self.page.run_js(interceptor_js) | |
| self.page.run_cdp('Page.addScriptToEvaluateOnNewDocument', source=interceptor_js) | |
| self.log("Console interceptor injected") | |
| except Exception as e: | |
| self.log(f"Injection failed: {e}") | |
| def collect(self) -> List[Dict]: | |
| """Собирает перехваченные логи""" | |
| if not self.page: | |
| return [] | |
| try: | |
| logs = self.page.run_js(''' | |
| const logs = window.__consoleLogs || []; | |
| window.__consoleLogs = []; | |
| return logs; | |
| ''') or [] | |
| # Фильтруем и логируем важные | |
| for log in logs: | |
| log_type = log.get('type', '') | |
| message = log.get('message', '') | |
| # Логируем ошибки и предупреждения | |
| if log_type in ('error', 'uncaught_error', 'unhandled_rejection'): | |
| self.log(f"ERROR: {message[:100]}...") | |
| elif log_type == 'warn' and any(x in message.lower() for x in ['fingerprint', 'fwcim', 'automation']): | |
| self.log(f"WARN: {message[:100]}...") | |
| self._logs.append(log) | |
| return logs | |
| except: | |
| return [] | |
| def on_step_end(self, step): | |
| """Добавляем логи к шагу""" | |
| step.console_logs = self._logs.copy() | |
| self._logs = [] | |
| def get_errors(self) -> List[Dict]: | |
| """Возвращает только ошибки""" | |
| return [log for log in self._logs if log.get('type') in ('error', 'uncaught_error', 'unhandled_rejection')] | |