feat(logging-p0): replace console.* with logger and add error logging before ERP throws
Eliminate console.* remnants in bootstrap, session-manager, migrations, and app entry so startup and login failures are captured in log files. Add log.error before all 14 throw sites in ERP services (auth, extractor, cleaner, browser manager) to ensure critical automation failures are traceable. Introduce capturePageContext utility for defensive Playwright page state capture during error logging. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,9 @@ import fs from 'fs'
|
|||||||
import { join } from 'path'
|
import { join } from 'path'
|
||||||
import { ConfigManager } from '../services/config/config-manager'
|
import { ConfigManager } from '../services/config/config-manager'
|
||||||
import { UpdateService } from '../services/update/update-service'
|
import { UpdateService } from '../services/update/update-service'
|
||||||
|
import { createLogger } from '../services/logger'
|
||||||
|
|
||||||
|
const log = createLogger('Bootstrap')
|
||||||
|
|
||||||
export function configurePlaywrightBrowsersPath(): string {
|
export function configurePlaywrightBrowsersPath(): string {
|
||||||
const browsersPath = join(app.getPath('userData'), 'ms-playwright')
|
const browsersPath = join(app.getPath('userData'), 'ms-playwright')
|
||||||
@@ -39,7 +42,7 @@ export function ensurePlaywrightRuntime(browsersPath: string): boolean {
|
|||||||
try {
|
try {
|
||||||
fs.mkdirSync(browsersPath, { recursive: true })
|
fs.mkdirSync(browsersPath, { recursive: true })
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to create browsers directory:', error)
|
log.error('Failed to create browsers directory', { error })
|
||||||
}
|
}
|
||||||
|
|
||||||
const newChromiumPath = join(browsersPath, 'chromium-1208', 'chrome-win64', 'chrome.exe')
|
const newChromiumPath = join(browsersPath, 'chromium-1208', 'chrome-win64', 'chrome.exe')
|
||||||
@@ -57,7 +60,7 @@ export function ensurePlaywrightRuntime(browsersPath: string): boolean {
|
|||||||
if (entry.startsWith('chromium-') && !entry.includes('headless')) {
|
if (entry.startsWith('chromium-') && !entry.includes('headless')) {
|
||||||
const revisionPath = join(browsersPath, entry, 'chrome-win64', 'chrome.exe')
|
const revisionPath = join(browsersPath, entry, 'chrome-win64', 'chrome.exe')
|
||||||
if (fs.existsSync(revisionPath)) {
|
if (fs.existsSync(revisionPath)) {
|
||||||
console.log('Found Chromium revision:', entry)
|
log.info('Found Chromium revision', { revision: entry })
|
||||||
foundRevision = true
|
foundRevision = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -71,10 +74,10 @@ export function ensurePlaywrightRuntime(browsersPath: string): boolean {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
console.warn(
|
log.warn('Playwright browser not found', {
|
||||||
'Playwright browser not found. Available:',
|
available: fs.existsSync(browsersPath) ? fs.readdirSync(browsersPath) : 'none',
|
||||||
fs.existsSync(browsersPath) ? fs.readdirSync(browsersPath) : 'none'
|
browsersPath
|
||||||
)
|
})
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,7 +87,7 @@ export async function initializeMainProcessServices(): Promise<void> {
|
|||||||
await configManager.initialize()
|
await configManager.initialize()
|
||||||
UpdateService.getInstance().initialize()
|
UpdateService.getInstance().initialize()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to initialize ConfigManager:', error)
|
log.error('Failed to initialize ConfigManager', { error })
|
||||||
}
|
}
|
||||||
|
|
||||||
const { registerIpcHandlers } = await import('../ipc')
|
const { registerIpcHandlers } = await import('../ipc')
|
||||||
|
|||||||
@@ -7,17 +7,20 @@ import {
|
|||||||
setupElectronRuntime
|
setupElectronRuntime
|
||||||
} from './bootstrap/runtime'
|
} from './bootstrap/runtime'
|
||||||
import { setupProcessGuards } from './bootstrap/process-guards'
|
import { setupProcessGuards } from './bootstrap/process-guards'
|
||||||
|
import { createLogger } from './services/logger'
|
||||||
|
|
||||||
|
const log = createLogger('App')
|
||||||
|
|
||||||
app.whenReady().then(async () => {
|
app.whenReady().then(async () => {
|
||||||
setupProcessGuards()
|
setupProcessGuards()
|
||||||
registerMainWindowLifecycle()
|
registerMainWindowLifecycle()
|
||||||
const playwrightBrowsersPath = configurePlaywrightBrowsersPath()
|
const playwrightBrowsersPath = configurePlaywrightBrowsersPath()
|
||||||
const browsersExist = ensurePlaywrightRuntime(playwrightBrowsersPath)
|
const browsersExist = ensurePlaywrightRuntime(playwrightBrowsersPath)
|
||||||
console.log('Playwright browsers exist:', browsersExist)
|
log.info('Playwright browsers check', { browsersExist })
|
||||||
await initializeMainProcessServices()
|
await initializeMainProcessServices()
|
||||||
setupElectronRuntime()
|
setupElectronRuntime()
|
||||||
|
|
||||||
ipcMain.on('ping', () => console.log('pong'))
|
ipcMain.on('ping', () => log.debug('pong'))
|
||||||
|
|
||||||
createMainWindow()
|
createMainWindow()
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -195,6 +195,10 @@ export class ErpBrowserManager {
|
|||||||
async navigate(url: string, options?: { timeout?: number }): Promise<void> {
|
async navigate(url: string, options?: { timeout?: number }): Promise<void> {
|
||||||
const page = this.session?.page
|
const page = this.session?.page
|
||||||
if (!page) {
|
if (!page) {
|
||||||
|
log.error('No page available for navigation', {
|
||||||
|
url,
|
||||||
|
hasSession: !!this.session
|
||||||
|
})
|
||||||
throw new Error('No page available. Call initialize() first.')
|
throw new Error('No page available. Call initialize() first.')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import type { CleanerInput, CleanerResult, OrderCleanDetail } from '../../types/
|
|||||||
import type { ErpSession } from '../../types/erp.types'
|
import type { ErpSession } from '../../types/erp.types'
|
||||||
import type { FrameLocator, Locator, Page } from 'playwright'
|
import type { FrameLocator, Locator, Page } from 'playwright'
|
||||||
import { createLogger, run, trackDuration } from '../logger'
|
import { createLogger, run, trackDuration } from '../logger'
|
||||||
|
import { capturePageContext } from './erp-error-context'
|
||||||
|
|
||||||
const log = createLogger('CleanerService')
|
const log = createLogger('CleanerService')
|
||||||
|
|
||||||
@@ -505,7 +506,10 @@ export class CleanerService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error('无法定位“备料计划”菜单项(可能菜单结构已变化)')
|
log.error('Failed to locate material plan menu item', {
|
||||||
|
attemptedSelectors: candidates.length
|
||||||
|
})
|
||||||
|
throw new Error('无法定位”备料计划”菜单项(可能菜单结构已变化)')
|
||||||
}
|
}
|
||||||
|
|
||||||
private async processDetailPage(params: {
|
private async processDetailPage(params: {
|
||||||
@@ -527,6 +531,9 @@ export class CleanerService {
|
|||||||
const dFrame = await detailMainFrame.contentFrame()
|
const dFrame = await detailMainFrame.contentFrame()
|
||||||
|
|
||||||
if (!dFrame) {
|
if (!dFrame) {
|
||||||
|
log.error('Failed to access detail page forward frame', {
|
||||||
|
...(await capturePageContext(detailPage))
|
||||||
|
})
|
||||||
throw new Error('Failed to access detail page forward frame')
|
throw new Error('Failed to access detail page forward frame')
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -535,6 +542,7 @@ export class CleanerService {
|
|||||||
const detailInnerFrame = await detailInnerLocator.contentFrame()
|
const detailInnerFrame = await detailInnerLocator.contentFrame()
|
||||||
|
|
||||||
if (!detailInnerFrame) {
|
if (!detailInnerFrame) {
|
||||||
|
log.error('Failed to access detail inner frame')
|
||||||
throw new Error('Failed to access detail inner frame')
|
throw new Error('Failed to access detail inner frame')
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -852,6 +860,7 @@ export class CleanerService {
|
|||||||
const rows = workFrame.locator('tbody tr')
|
const rows = workFrame.locator('tbody tr')
|
||||||
const rowCount = await rows.count()
|
const rowCount = await rows.count()
|
||||||
if (rowCount === 0) {
|
if (rowCount === 0) {
|
||||||
|
log.error('Retry query returned no results', { orderNumber, rowCount })
|
||||||
throw new Error('订单重试查询无结果')
|
throw new Error('订单重试查询无结果')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { chromium } from 'playwright'
|
import { chromium } from 'playwright'
|
||||||
import type { ErpConfig, ErpSession } from '../../types/erp.types'
|
import type { ErpConfig, ErpSession } from '../../types/erp.types'
|
||||||
import { createLogger } from '../logger'
|
import { createLogger } from '../logger'
|
||||||
|
import { capturePageContext } from './erp-error-context'
|
||||||
|
|
||||||
const log = createLogger('ErpAuthService')
|
const log = createLogger('ErpAuthService')
|
||||||
|
|
||||||
@@ -70,6 +71,9 @@ export class ErpAuthService {
|
|||||||
const contentFrame = await frameLocator.contentFrame()
|
const contentFrame = await frameLocator.contentFrame()
|
||||||
|
|
||||||
if (!contentFrame) {
|
if (!contentFrame) {
|
||||||
|
log.error('Failed to access forwardFrame content frame', {
|
||||||
|
...(await capturePageContext(page))
|
||||||
|
})
|
||||||
throw new Error('Failed to access forwardFrame content frame')
|
throw new Error('Failed to access forwardFrame content frame')
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,6 +84,9 @@ export class ErpAuthService {
|
|||||||
try {
|
try {
|
||||||
await contentFrame.getByRole('textbox', { name: '用户名' }).fill(this.config.username)
|
await contentFrame.getByRole('textbox', { name: '用户名' }).fill(this.config.username)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
log.error('Failed to find username input', {
|
||||||
|
error: e instanceof Error ? e.message : String(e)
|
||||||
|
})
|
||||||
throw new Error(`Failed to find username input: ${e}`)
|
throw new Error(`Failed to find username input: ${e}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,6 +94,9 @@ export class ErpAuthService {
|
|||||||
try {
|
try {
|
||||||
await contentFrame.getByRole('textbox', { name: '密码' }).fill(this.config.password)
|
await contentFrame.getByRole('textbox', { name: '密码' }).fill(this.config.password)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
log.error('Failed to find password input', {
|
||||||
|
error: e instanceof Error ? e.message : String(e)
|
||||||
|
})
|
||||||
throw new Error(`Failed to find password input: ${e}`)
|
throw new Error(`Failed to find password input: ${e}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,6 +104,9 @@ export class ErpAuthService {
|
|||||||
try {
|
try {
|
||||||
await contentFrame.getByRole('button', { name: '登录' }).click()
|
await contentFrame.getByRole('button', { name: '登录' }).click()
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
log.error('Failed to click login button', {
|
||||||
|
error: e instanceof Error ? e.message : String(e)
|
||||||
|
})
|
||||||
throw new Error(`Failed to click login button: ${e}`)
|
throw new Error(`Failed to click login button: ${e}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,6 +151,7 @@ export class ErpAuthService {
|
|||||||
|
|
||||||
const hasError = await errorLocator.isVisible()
|
const hasError = await errorLocator.isVisible()
|
||||||
if (hasError) {
|
if (hasError) {
|
||||||
|
log.error('ERP login failed: incorrect username or password')
|
||||||
throw new Error('ERP 登录失败:名称或密码错误')
|
throw new Error('ERP 登录失败:名称或密码错误')
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,6 +163,7 @@ export class ErpAuthService {
|
|||||||
|
|
||||||
const hasError = await errorLocator.isVisible().catch(() => false)
|
const hasError = await errorLocator.isVisible().catch(() => false)
|
||||||
if (hasError) {
|
if (hasError) {
|
||||||
|
log.error('ERP login failed: incorrect username or password (retry check)')
|
||||||
throw new Error('ERP 登录失败:名称或密码错误')
|
throw new Error('ERP 登录失败:名称或密码错误')
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,6 +187,7 @@ export class ErpAuthService {
|
|||||||
*/
|
*/
|
||||||
getSession(): ErpSession {
|
getSession(): ErpSession {
|
||||||
if (!this.session?.isLoggedIn) {
|
if (!this.session?.isLoggedIn) {
|
||||||
|
log.error('getSession called without active session')
|
||||||
throw new Error('Not logged in. Call login() first.')
|
throw new Error('Not logged in. Call login() first.')
|
||||||
}
|
}
|
||||||
return this.session
|
return this.session
|
||||||
|
|||||||
47
src/main/services/erp/erp-error-context.ts
Normal file
47
src/main/services/erp/erp-error-context.ts
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
/**
|
||||||
|
* ERP Error Context Capture
|
||||||
|
*
|
||||||
|
* Lightweight helper to capture Playwright page state when ERP operations fail.
|
||||||
|
* All capture calls are defensive — failures do not propagate to the caller.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { Page } from 'playwright'
|
||||||
|
|
||||||
|
export interface ErpErrorContext {
|
||||||
|
pageUrl?: string
|
||||||
|
frameHierarchy?: Array<{ name: string; url: string }>
|
||||||
|
targetSelector?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Capture the current state of a Playwright page for error logging.
|
||||||
|
* Returns a plain object safe for structured logging.
|
||||||
|
*
|
||||||
|
* @param page - The Playwright page to inspect
|
||||||
|
* @param targetSelector - Optional selector that was being targeted
|
||||||
|
*/
|
||||||
|
export async function capturePageContext(
|
||||||
|
page: Page,
|
||||||
|
targetSelector?: string
|
||||||
|
): Promise<ErpErrorContext> {
|
||||||
|
const ctx: ErpErrorContext = {}
|
||||||
|
|
||||||
|
try {
|
||||||
|
ctx.pageUrl = page.url()
|
||||||
|
} catch {
|
||||||
|
// page may be closed or inaccessible
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const frames = page.frames()
|
||||||
|
ctx.frameHierarchy = frames.map((f) => ({ name: f.name(), url: f.url() }))
|
||||||
|
} catch {
|
||||||
|
// frame enumeration may fail on detached pages
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targetSelector) {
|
||||||
|
ctx.targetSelector = targetSelector
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctx
|
||||||
|
}
|
||||||
@@ -6,6 +6,10 @@ import type {
|
|||||||
ExtractorCoreResult,
|
ExtractorCoreResult,
|
||||||
ExtractionProgress
|
ExtractionProgress
|
||||||
} from '../../types/extractor.types'
|
} from '../../types/extractor.types'
|
||||||
|
import { createLogger } from '../logger'
|
||||||
|
import { capturePageContext } from './erp-error-context'
|
||||||
|
|
||||||
|
const log = createLogger('ExtractorCore')
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ExtractorCore - Handles all web page operations for data extraction
|
* ExtractorCore - Handles all web page operations for data extraction
|
||||||
@@ -97,6 +101,9 @@ export class ExtractorCore {
|
|||||||
const fFrame = await forwardFrameLocator.contentFrame()
|
const fFrame = await forwardFrameLocator.contentFrame()
|
||||||
|
|
||||||
if (!fFrame) {
|
if (!fFrame) {
|
||||||
|
log.error('Failed to access popup forward frame', {
|
||||||
|
...(await capturePageContext(popupPage))
|
||||||
|
})
|
||||||
throw new Error('Failed to access popup forward frame')
|
throw new Error('Failed to access popup forward frame')
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,6 +112,7 @@ export class ExtractorCore {
|
|||||||
const workFrame = await innerFrameLocator.contentFrame()
|
const workFrame = await innerFrameLocator.contentFrame()
|
||||||
|
|
||||||
if (!workFrame) {
|
if (!workFrame) {
|
||||||
|
log.error('Failed to access inner work frame')
|
||||||
throw new Error('Failed to access inner work frame')
|
throw new Error('Failed to access inner work frame')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ import { dirname } from 'path'
|
|||||||
import { ConfigManager } from '../../config/config-manager'
|
import { ConfigManager } from '../../config/config-manager'
|
||||||
import { MySqlService } from '../../database/mysql'
|
import { MySqlService } from '../../database/mysql'
|
||||||
import { SqlServerService } from '../../database/sql-server'
|
import { SqlServerService } from '../../database/sql-server'
|
||||||
|
import { createLogger } from '../../logger'
|
||||||
|
|
||||||
|
const log = createLogger('Migration')
|
||||||
|
|
||||||
const __filename = fileURLToPath(import.meta.url)
|
const __filename = fileURLToPath(import.meta.url)
|
||||||
const __dirname = dirname(__filename)
|
const __dirname = dirname(__filename)
|
||||||
@@ -136,7 +139,9 @@ async function runMySQLMigration(configManager: ConfigManager): Promise<void> {
|
|||||||
|
|
||||||
await mysqlService.disconnect()
|
await mysqlService.disconnect()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('✗ MySQL Migration failed:', error instanceof Error ? error.message : error)
|
log.error('MySQL Migration failed', {
|
||||||
|
error: error instanceof Error ? error.message : String(error)
|
||||||
|
})
|
||||||
if (mysqlService.isConnected()) {
|
if (mysqlService.isConnected()) {
|
||||||
await mysqlService.disconnect()
|
await mysqlService.disconnect()
|
||||||
}
|
}
|
||||||
@@ -192,7 +197,9 @@ async function runSqlServerMigration(configManager: ConfigManager): Promise<void
|
|||||||
|
|
||||||
await sqlServerService.disconnect()
|
await sqlServerService.disconnect()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('✗ SQL Server Migration failed:', error instanceof Error ? error.message : error)
|
log.error('SQL Server Migration failed', {
|
||||||
|
error: error instanceof Error ? error.message : String(error)
|
||||||
|
})
|
||||||
if (sqlServerService.isConnected()) {
|
if (sqlServerService.isConnected()) {
|
||||||
await sqlServerService.disconnect()
|
await sqlServerService.disconnect()
|
||||||
}
|
}
|
||||||
@@ -223,7 +230,7 @@ async function main(): Promise<void> {
|
|||||||
|
|
||||||
console.log('\n✅ Migration completed successfully!\n')
|
console.log('\n✅ Migration completed successfully!\n')
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('\n❌ Migration failed:', error instanceof Error ? error.message : error)
|
log.error('Migration failed', { error: error instanceof Error ? error.message : String(error) })
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ import * as fs from 'fs'
|
|||||||
import * as path from 'path'
|
import * as path from 'path'
|
||||||
import yaml from 'js-yaml'
|
import yaml from 'js-yaml'
|
||||||
import { z } from 'zod'
|
import { z } from 'zod'
|
||||||
|
import { createLogger } from '../../logger'
|
||||||
|
|
||||||
|
const log = createLogger('MigrationRunner')
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MySQL configuration schema
|
* MySQL configuration schema
|
||||||
@@ -105,8 +108,10 @@ async function runMigration(): Promise<void> {
|
|||||||
try {
|
try {
|
||||||
dbConfig = loadConfig(configPath)
|
dbConfig = loadConfig(configPath)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to load config.yaml:', error instanceof Error ? error.message : error)
|
log.error('Failed to load config', {
|
||||||
console.error('Please ensure config.yaml exists and contains valid MySQL configuration.')
|
error: error instanceof Error ? error.message : String(error),
|
||||||
|
configPath
|
||||||
|
})
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,8 +176,7 @@ async function runMigration(): Promise<void> {
|
|||||||
console.log(` ERP_Password = 'your_password'`)
|
console.log(` ERP_Password = 'your_password'`)
|
||||||
console.log(` WHERE ERP_URL IS NULL;\n`)
|
console.log(` WHERE ERP_URL IS NULL;\n`)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('\n❌ Migration failed with error:')
|
log.error('Migration failed', { error })
|
||||||
console.error(error)
|
|
||||||
console.error('\nTroubleshooting:')
|
console.error('\nTroubleshooting:')
|
||||||
console.error('1. Check if MySQL server is running')
|
console.error('1. Check if MySQL server is running')
|
||||||
console.error('2. Verify database credentials in config.yaml file')
|
console.error('2. Verify database credentials in config.yaml file')
|
||||||
@@ -194,6 +198,6 @@ async function runMigration(): Promise<void> {
|
|||||||
|
|
||||||
// Run migration
|
// Run migration
|
||||||
runMigration().catch((error) => {
|
runMigration().catch((error) => {
|
||||||
console.error('Unexpected error:', error)
|
log.error('Unexpected error', { error })
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -9,6 +9,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import type { UserInfo } from '../../types/user.types'
|
import type { UserInfo } from '../../types/user.types'
|
||||||
|
import { createLogger } from '../logger'
|
||||||
|
|
||||||
|
const log = createLogger('SessionManager')
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Session Manager Class
|
* Session Manager Class
|
||||||
@@ -59,12 +62,12 @@ export class SessionManager {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[SessionManager] Login error:', error)
|
log.error('Login error', { error })
|
||||||
return false
|
return false
|
||||||
} finally {
|
} finally {
|
||||||
if (dao) {
|
if (dao) {
|
||||||
await dao.disconnect().catch((error) => {
|
await dao.disconnect().catch((error) => {
|
||||||
console.error('[SessionManager] Login disconnect error:', error)
|
log.error('Login disconnect error', { error })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -93,12 +96,12 @@ export class SessionManager {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[SessionManager] Silent login error:', error)
|
log.error('Silent login error', { error })
|
||||||
return false
|
return false
|
||||||
} finally {
|
} finally {
|
||||||
if (dao) {
|
if (dao) {
|
||||||
await dao.disconnect().catch((error) => {
|
await dao.disconnect().catch((error) => {
|
||||||
console.error('[SessionManager] Silent login disconnect error:', error)
|
log.error('Silent login disconnect error', { error })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -187,12 +190,12 @@ export class SessionManager {
|
|||||||
dao = new BIPUsersDAO()
|
dao = new BIPUsersDAO()
|
||||||
return await dao.getAllUsers()
|
return await dao.getAllUsers()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[SessionManager] Get all users error:', error)
|
log.error('Get all users error', { error })
|
||||||
return []
|
return []
|
||||||
} finally {
|
} finally {
|
||||||
if (dao) {
|
if (dao) {
|
||||||
await dao.disconnect().catch((error) => {
|
await dao.disconnect().catch((error) => {
|
||||||
console.error('[SessionManager] Get all users disconnect error:', error)
|
log.error('Get all users disconnect error', { error })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user