Fix error

This commit is contained in:
2025-11-13 20:23:57 +01:00
parent e098bdec64
commit 5651f62088
5 changed files with 105 additions and 20 deletions

View File

@@ -179,18 +179,51 @@ export default class BrowserUtil {
const browser = page.context()
const pages = browser.pages()
// IMPROVED: If no pages exist, create a new one instead of throwing error
if (pages.length === 0) {
this.bot.log(this.bot.isMobile, 'GET-NEW-TAB', 'No pages found in context, creating new page', 'warn')
const newPage = await browser.newPage()
await this.bot.utils.wait(500)
return newPage
}
const newTab = pages[pages.length - 1]
if (newTab) {
// IMPROVED: Verify the page is not closed before returning
if (newTab && !newTab.isClosed()) {
return newTab
}
this.bot.log(this.bot.isMobile, 'GET-NEW-TAB', 'Unable to get latest tab', 'error')
throw new Error('Unable to get latest tab - no pages found in browser context')
// IMPROVED: If latest tab is closed, find first non-closed tab or create new one
const openPage = pages.find(p => !p.isClosed())
if (openPage) {
this.bot.log(this.bot.isMobile, 'GET-NEW-TAB', 'Latest tab was closed, using first available open tab')
return openPage
}
// IMPROVED: Last resort - create new page
this.bot.log(this.bot.isMobile, 'GET-NEW-TAB', 'All tabs were closed, creating new page', 'warn')
const newPage = await browser.newPage()
await this.bot.utils.wait(500)
return newPage
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error)
this.bot.log(this.bot.isMobile, 'GET-NEW-TAB', 'An error occurred: ' + errorMessage, 'error')
throw new Error('Get new tab failed: ' + errorMessage)
this.bot.log(this.bot.isMobile, 'GET-NEW-TAB', 'Critical error in getLatestTab: ' + errorMessage, 'error')
// IMPROVED: Try one more time to create a new page as absolute last resort
try {
const browser = page.context()
this.bot.log(this.bot.isMobile, 'GET-NEW-TAB', 'Attempting recovery by creating new page', 'warn')
const recoveryPage = await browser.newPage()
await this.bot.utils.wait(500)
return recoveryPage
} catch (recoveryError) {
const recoveryMsg = recoveryError instanceof Error ? recoveryError.message : String(recoveryError)
this.bot.log(this.bot.isMobile, 'GET-NEW-TAB', 'Recovery failed: ' + recoveryMsg, 'error')
throw new Error('Get new tab failed and recovery unsuccessful: ' + errorMessage)
}
}
}

View File

@@ -124,7 +124,14 @@ export class DesktopFlow {
// Do desktop searches
if (this.bot.config.workers.doDesktopSearch) {
await this.bot.activities.doSearch(workerPage, data)
try {
await this.bot.activities.doSearch(workerPage, data)
} catch (searchError) {
const errorMsg = searchError instanceof Error ? searchError.message : String(searchError)
this.bot.log(false, 'DESKTOP-FLOW', `Desktop search failed: ${errorMsg}`, 'error')
// IMPROVED: Don't throw - continue with other tasks, just log the error
// User will see reduced points but flow completes
}
}
// Fetch points BEFORE closing (avoid page closed reload error)

View File

@@ -136,7 +136,14 @@ export class MobileFlow {
// Go to homepage on worker page
await this.bot.browser.func.goHome(workerPage)
await this.bot.activities.doSearch(workerPage, data)
// IMPROVED: Add error handling for mobile search to prevent flow termination
try {
await this.bot.activities.doSearch(workerPage, data)
} catch (searchError) {
const errorMsg = searchError instanceof Error ? searchError.message : String(searchError)
this.bot.log(true, 'MOBILE-FLOW', `Mobile search failed: ${errorMsg}`, 'error')
// Continue execution - let retry logic handle it below
}
// Fetch current search points
const mobileSearchPoints = (await this.bot.browser.func.getSearchPoints()).mobileSearch?.[0]

View File

@@ -28,7 +28,14 @@ export class Search extends Workers {
public async doSearch(page: Page, data: DashboardData) {
this.bot.log(this.bot.isMobile, 'SEARCH-BING', 'Starting Bing searches')
page = await this.bot.browser.utils.getLatestTab(page)
// IMPROVED: Add error handling for getLatestTab to prevent early flow failure
try {
page = await this.bot.browser.utils.getLatestTab(page)
} catch (error) {
const errorMsg = error instanceof Error ? error.message : String(error)
this.bot.log(this.bot.isMobile, 'SEARCH-BING', `Failed to get latest tab: ${errorMsg}`, 'error')
throw new Error(`Cannot start search - tab retrieval failed: ${errorMsg}`)
}
let searchCounters: Counters = await this.bot.browser.func.getSearchPoints()
let missingPoints = this.calculatePoints(searchCounters)

View File

@@ -1,4 +1,6 @@
import axios from 'axios'
import fs from 'fs'
import path from 'path'
import { DISCORD } from '../../constants'
import { Config } from '../../interface/Config'
@@ -188,40 +190,49 @@ export async function sendErrorReport(
Object.assign(payload.context, sanitizedContext)
}
// Build Discord embed
// Build Discord embed with improved formatting
const embed = {
title: '🐛 Automatic Error Report',
description: `\`\`\`\n${sanitizedMessage.slice(0, 500)}\n\`\`\``,
description: `\`\`\`js\n${sanitizedMessage.slice(0, 700)}\n\`\`\``,
color: DISCORD.COLOR_RED,
fields: [
{
name: '📦 Version',
value: payload.context.version,
value: payload.context.version === 'unknown' ? '⚠️ Unknown (check package.json)' : `v${payload.context.version}`,
inline: true
},
{
name: '💻 Platform',
value: `${payload.context.platform} (${payload.context.arch})`,
value: `${payload.context.platform} ${payload.context.arch}`,
inline: true
},
{
name: '⚙️ Node.js',
value: payload.context.nodeVersion,
inline: true
},
{
name: '🕐 Timestamp',
value: new Date(payload.context.timestamp).toLocaleString('en-US', { timeZone: 'UTC', timeZoneName: 'short' }),
inline: false
}
],
timestamp: payload.context.timestamp,
footer: {
text: 'Automatic error reporting - Thank you for contributing!',
text: 'Automatic error reporting • Non-sensitive data only',
icon_url: DISCORD.AVATAR_URL
}
}
// Add stack trace field if available (truncated)
// Add stack trace field if available (truncated to fit Discord limits)
if (sanitizedStack) {
// Limit to 900 chars to leave room for backticks and formatting
const truncated = sanitizedStack.slice(0, 900)
const wasTruncated = sanitizedStack.length > 900
embed.fields.push({
name: '📋 Stack Trace (truncated)',
value: `\`\`\`\n${sanitizedStack.slice(0, 800)}\n\`\`\``,
name: '📋 Stack Trace' + (wasTruncated ? ' (truncated for display)' : ''),
value: `\`\`\`js\n${truncated}${wasTruncated ? '\n... (see full trace in logs)' : ''}\n\`\`\``,
inline: false
})
}
@@ -262,13 +273,33 @@ export async function sendErrorReport(
/**
* Get project version from package.json
* FIXED: Use path.join to correctly resolve package.json location in both dev and production
*/
function getProjectVersion(): string {
try {
// Dynamic import for package.json
// eslint-disable-next-line @typescript-eslint/no-var-requires
const packageJson = require('../../package.json') as { version?: string }
return packageJson.version || 'unknown'
// Try multiple possible paths (dev and compiled)
const possiblePaths = [
path.join(__dirname, '../../../package.json'), // From dist/util/notifications/
path.join(__dirname, '../../package.json'), // From src/util/notifications/
path.join(process.cwd(), 'package.json') // From project root
]
for (const pkgPath of possiblePaths) {
try {
if (fs.existsSync(pkgPath)) {
const raw = fs.readFileSync(pkgPath, 'utf-8')
const pkg = JSON.parse(raw) as { version?: string }
if (pkg.version) {
return pkg.version
}
}
} catch {
// Try next path
continue
}
}
return 'unknown'
} catch {
return 'unknown'
}