mirror of
https://github.com/LightZirconite/Microsoft-Rewards-Bot.git
synced 2026-01-18 12:43:57 +00:00
Refactor: Enhance error handling and logging in Browser and MicrosoftRewardsBot classes; remove unused luxon declarations
This commit is contained in:
@@ -21,7 +21,9 @@ class Browser {
|
||||
// Dynamically import child_process to avoid overhead otherwise
|
||||
const { execSync } = await import('child_process')
|
||||
execSync('npx playwright install chromium', { stdio: 'ignore' })
|
||||
} catch { /* silent */ }
|
||||
} catch (e) {
|
||||
this.bot.log(this.bot.isMobile, 'BROWSER', `Auto-install failed: ${e instanceof Error ? e.message : String(e)}`, 'warn')
|
||||
}
|
||||
}
|
||||
|
||||
let browser: import('rebrowser-playwright').Browser
|
||||
@@ -114,11 +116,18 @@ class Browser {
|
||||
}
|
||||
`
|
||||
document.documentElement.appendChild(style)
|
||||
} catch { /* ignore */ }
|
||||
} catch (e) {
|
||||
// Style injection failed - not critical, page will still function
|
||||
}
|
||||
})
|
||||
} catch { /* ignore */ }
|
||||
} catch (e) {
|
||||
// Viewport/script setup failed - log for debugging but continue
|
||||
this.bot.log(this.bot.isMobile, 'BROWSER', `Page setup warning: ${e instanceof Error ? e.message : String(e)}`, 'warn')
|
||||
}
|
||||
})
|
||||
} catch { /* ignore */ }
|
||||
} catch (e) {
|
||||
this.bot.log(this.bot.isMobile, 'BROWSER', `Context event handler setup warning: ${e instanceof Error ? e.message : String(e)}`, 'warn')
|
||||
}
|
||||
|
||||
await context.addCookies(sessionData.cookies)
|
||||
|
||||
|
||||
33
src/index.ts
33
src/index.ts
@@ -300,7 +300,9 @@ export class MicrosoftRewardsBot {
|
||||
this.log(false, 'BUY-MODE', 'Monitor tab was closed; reopening in background...', 'warn')
|
||||
await recreateMonitor()
|
||||
}
|
||||
} catch { /* ignore */ }
|
||||
} catch (e) {
|
||||
this.log(false, 'BUY-MODE', `Failed to check/recreate monitor tab: ${e instanceof Error ? e.message : String(e)}`, 'warn')
|
||||
}
|
||||
|
||||
try {
|
||||
const data = await this.browser.func.getDashboardData(monitor)
|
||||
@@ -321,9 +323,14 @@ export class MicrosoftRewardsBot {
|
||||
const msg = err instanceof Error ? err.message : String(err)
|
||||
if (/Target closed|page has been closed|browser has been closed/i.test(msg)) {
|
||||
this.log(false, 'BUY-MODE', 'Monitor page closed or lost; recreating...', 'warn')
|
||||
try { await recreateMonitor() } catch { /* ignore */ }
|
||||
try {
|
||||
await recreateMonitor()
|
||||
} catch (e) {
|
||||
this.log(false, 'BUY-MODE', `Failed to recreate monitor: ${e instanceof Error ? e.message : String(e)}`, 'warn')
|
||||
}
|
||||
} else {
|
||||
this.log(false, 'BUY-MODE', `Dashboard check error: ${msg}`, 'warn')
|
||||
}
|
||||
// Swallow other errors to avoid disrupting the user
|
||||
}
|
||||
}
|
||||
|
||||
@@ -333,7 +340,11 @@ export class MicrosoftRewardsBot {
|
||||
} catch (e) {
|
||||
log(false, 'BUY-MODE', `Failed to save session: ${e instanceof Error ? e.message : String(e)}`, 'warn')
|
||||
}
|
||||
try { if (!monitor.isClosed()) await monitor.close() } catch {/* ignore */}
|
||||
try {
|
||||
if (!monitor.isClosed()) await monitor.close()
|
||||
} catch (e) {
|
||||
log(false, 'BUY-MODE', `Failed to close monitor tab: ${e instanceof Error ? e.message : String(e)}`, 'warn')
|
||||
}
|
||||
|
||||
// Send a final minimal conclusion webhook for this manual session
|
||||
const summary: AccountSummary = {
|
||||
@@ -351,7 +362,7 @@ export class MicrosoftRewardsBot {
|
||||
|
||||
this.log(false, 'BUY-MODE', 'Buy mode session finished (monitoring period ended). You can close the browser when done.')
|
||||
} catch (e) {
|
||||
this.log(false, 'BUY-MODE', `Error in buy mode: ${e instanceof Error ? e.message : e}`, 'error')
|
||||
this.log(false, 'BUY-MODE', `Error in buy mode: ${e instanceof Error ? e.message : String(e)}`, 'error')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -506,10 +517,14 @@ export class MicrosoftRewardsBot {
|
||||
(async () => {
|
||||
try {
|
||||
await this.sendConclusion(this.accountSummaries)
|
||||
} catch {/* ignore */}
|
||||
} catch (e) {
|
||||
log('main', 'CONCLUSION', `Failed to send conclusion: ${e instanceof Error ? e.message : String(e)}`, 'warn')
|
||||
}
|
||||
try {
|
||||
await this.runAutoUpdate()
|
||||
} catch {/* ignore */}
|
||||
} catch (e) {
|
||||
log('main', 'UPDATE', `Auto-update failed: ${e instanceof Error ? e.message : String(e)}`, 'warn')
|
||||
}
|
||||
log('main', 'MAIN-WORKER', 'All workers destroyed. Exiting main process!', 'warn')
|
||||
process.exit(0)
|
||||
})()
|
||||
@@ -806,7 +821,9 @@ export class MicrosoftRewardsBot {
|
||||
// Single process mode -> build and send conclusion directly
|
||||
await this.sendConclusion(this.accountSummaries)
|
||||
// After conclusion, run optional auto-update
|
||||
await this.runAutoUpdate().catch(() => {/* ignore update errors */})
|
||||
await this.runAutoUpdate().catch((e) => {
|
||||
log('main', 'UPDATE', `Auto-update failed: ${e instanceof Error ? e.message : String(e)}`, 'warn')
|
||||
})
|
||||
}
|
||||
process.exit()
|
||||
}
|
||||
|
||||
7
src/luxon.d.ts
vendored
7
src/luxon.d.ts
vendored
@@ -1,7 +0,0 @@
|
||||
/* Minimal ambient declarations to unblock TypeScript when @types/luxon is absent. */
|
||||
declare module 'luxon' {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export const DateTime: any
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export const IANAZone: any
|
||||
}
|
||||
@@ -19,13 +19,19 @@ export class Humanizer {
|
||||
if (Math.random() < moveProb) {
|
||||
const x = Math.floor(Math.random() * 40) + 5
|
||||
const y = Math.floor(Math.random() * 30) + 5
|
||||
await page.mouse.move(x, y, { steps: 2 }).catch(() => {})
|
||||
await page.mouse.move(x, y, { steps: 2 }).catch(() => {
|
||||
// Mouse move failed - page may be closed or unavailable
|
||||
})
|
||||
}
|
||||
if (Math.random() < scrollProb) {
|
||||
const dy = (Math.random() < 0.5 ? 1 : -1) * (Math.floor(Math.random() * 150) + 50)
|
||||
await page.mouse.wheel(0, dy).catch(() => {})
|
||||
await page.mouse.wheel(0, dy).catch(() => {
|
||||
// Mouse wheel failed - page may be closed or unavailable
|
||||
})
|
||||
}
|
||||
} catch {/* noop */}
|
||||
} catch {
|
||||
// Gesture execution failed - not critical for operation
|
||||
}
|
||||
}
|
||||
|
||||
async actionPause(): Promise<void> {
|
||||
@@ -40,7 +46,10 @@ export class Humanizer {
|
||||
try {
|
||||
const n = this.util.stringToMs(String(v))
|
||||
return Math.max(0, Math.min(n, 10_000))
|
||||
} catch { return defMin }
|
||||
} catch (e) {
|
||||
// Parse failed - use default minimum
|
||||
return defMin
|
||||
}
|
||||
}
|
||||
min = parse(this.cfg.actionDelay.min)
|
||||
max = parse(this.cfg.actionDelay.max)
|
||||
|
||||
@@ -260,7 +260,15 @@ export function loadAccounts(): Account[] {
|
||||
]
|
||||
let chosen: string | null = null
|
||||
for (const p of candidates) {
|
||||
try { if (fs.existsSync(p)) { chosen = p; break } } catch { /* ignore */ }
|
||||
try {
|
||||
if (fs.existsSync(p)) {
|
||||
chosen = p
|
||||
break
|
||||
}
|
||||
} catch (e) {
|
||||
// Filesystem check failed for this path, try next
|
||||
continue
|
||||
}
|
||||
}
|
||||
if (!chosen) throw new Error(`accounts file not found in: ${candidates.join(' | ')}`)
|
||||
raw = fs.readFileSync(chosen, 'utf-8')
|
||||
@@ -349,7 +357,15 @@ export function loadConfig(): Config {
|
||||
|
||||
let cfgPath: string | null = null
|
||||
for (const p of candidates) {
|
||||
try { if (fs.existsSync(p)) { cfgPath = p; break } } catch { /* ignore */ }
|
||||
try {
|
||||
if (fs.existsSync(p)) {
|
||||
cfgPath = p
|
||||
break
|
||||
}
|
||||
} catch (e) {
|
||||
// Filesystem check failed for this path, try next
|
||||
continue
|
||||
}
|
||||
}
|
||||
if (!cfgPath) throw new Error(`config.json not found in: ${candidates.join(' | ')}`)
|
||||
const config = fs.readFileSync(cfgPath, 'utf-8')
|
||||
@@ -377,6 +393,8 @@ export async function loadSessionData(sessionPath: string, email: string, isMobi
|
||||
}
|
||||
|
||||
// Fetch fingerprint file (support both legacy typo "fingerpint" and corrected "fingerprint")
|
||||
// NOTE: "fingerpint" is a historical typo that must be maintained for backwards compatibility
|
||||
// with existing session files. We check for the corrected name first, then fall back to the typo.
|
||||
const baseDir = path.join(__dirname, '../browser/', sessionPath, email)
|
||||
const legacyFile = path.join(baseDir, `${isMobile ? 'mobile_fingerpint' : 'desktop_fingerpint'}.json`)
|
||||
const correctFile = path.join(baseDir, `${isMobile ? 'mobile_fingerprint' : 'desktop_fingerprint'}.json`)
|
||||
@@ -436,11 +454,18 @@ export async function saveFingerprintData(sessionPath: string, email: string, is
|
||||
}
|
||||
|
||||
// Save fingerprint to files (write both legacy and corrected names for compatibility)
|
||||
// NOTE: Writing to both "fingerpint" (typo) and "fingerprint" (correct) ensures backwards
|
||||
// compatibility with older bot versions that expect the typo filename.
|
||||
const legacy = path.join(sessionDir, `${isMobile ? 'mobile_fingerpint' : 'desktop_fingerpint'}.json`)
|
||||
const correct = path.join(sessionDir, `${isMobile ? 'mobile_fingerprint' : 'desktop_fingerprint'}.json`)
|
||||
const payload = JSON.stringify(fingerprint)
|
||||
await fs.promises.writeFile(correct, payload)
|
||||
try { await fs.promises.writeFile(legacy, payload) } catch { /* ignore */ }
|
||||
try {
|
||||
await fs.promises.writeFile(legacy, payload)
|
||||
} catch (e) {
|
||||
// Legacy file write failed - not critical since correct file was written
|
||||
// Silently continue to maintain compatibility
|
||||
}
|
||||
|
||||
return sessionDir
|
||||
} catch (error) {
|
||||
|
||||
Reference in New Issue
Block a user