fix: improve error handling and logging for extractor and cleaner

- Load .env file in main process using dotenv
- Add detailed console logging for debugging
- Add validation for ERP configuration before extraction
- Improve error display in UI with selectable text
- Add stack trace logging for better debugging
This commit is contained in:
Misaka
2026-03-01 16:07:47 +08:00
parent e794470d69
commit e04337dc19
4 changed files with 91 additions and 16 deletions

View File

@@ -3,6 +3,14 @@ import { join } from 'path'
import { electronApp, optimizer, is } from '@electron-toolkit/utils' import { electronApp, optimizer, is } from '@electron-toolkit/utils'
import icon from '../../resources/icon.png?asset' import icon from '../../resources/icon.png?asset'
import { registerIpcHandlers } from './ipc' import { registerIpcHandlers } from './ipc'
import * as dotenv from 'dotenv'
import { fileURLToPath } from 'url'
import { dirname, resolve } from 'path'
// Load environment variables from .env file
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)
dotenv.config({ path: resolve(__dirname, '../../.env') })
function createWindow(): void { function createWindow(): void {
// Create the browser window. // Create the browser window.

View File

@@ -16,31 +16,54 @@ export function registerCleanerHandlers(): void {
let authService: ErpAuthService | null = null let authService: ErpAuthService | null = null
try { try {
// Check environment variables
const erpUrl = process.env.ERP_URL || ''
const erpUsername = process.env.ERP_USERNAME || ''
const erpPassword = process.env.ERP_PASSWORD || ''
console.log('[Cleaner] Config:', {
url: erpUrl ? '***' : 'EMPTY',
username: erpUsername ? '***' : 'EMPTY'
})
if (!erpUrl || !erpUsername || !erpPassword) {
throw new Error(
'ERP 配置不完整。请检查 .env 文件中的 ERP_URL, ERP_USERNAME, ERP_PASSWORD'
)
}
// Create auth service and login // Create auth service and login
authService = new ErpAuthService({ authService = new ErpAuthService({
url: process.env.ERP_URL || '', url: erpUrl,
username: process.env.ERP_USERNAME || '', username: erpUsername,
password: process.env.ERP_PASSWORD || '', password: erpPassword,
headless: true headless: true
}) })
console.log('[Cleaner] Logging in to ERP...')
await authService.login() await authService.login()
console.log('[Cleaner] Login successful')
// Create cleaner service and run cleaning // Create cleaner service and run cleaning
const cleaner = new CleanerService(authService) const cleaner = new CleanerService(authService)
console.log('[Cleaner] Starting cleaning:', input)
const result = await cleaner.clean(input) const result = await cleaner.clean(input)
console.log('[Cleaner] Cleaning completed:', result)
return { success: true, data: result } return { success: true, data: result }
} catch (error) { } catch (error) {
const message = error instanceof Error ? error.message : 'Unknown error' const message = error instanceof Error ? error.message : 'Unknown error'
return { success: false, error: message } console.error('[Cleaner] Error:', message)
console.error('[Cleaner] Stack:', error instanceof Error ? error.stack : 'N/A')
return { success: false, error: `清理失败:${message}` }
} finally { } finally {
// Clean up: close browser // Clean up: close browser
if (authService) { if (authService) {
try { try {
await authService.close() await authService.close()
} catch { console.log('[Cleaner] Browser closed')
// Ignore cleanup errors } catch (closeError) {
console.warn('[Cleaner] Error closing browser:', closeError)
} }
} }
} }

View File

@@ -16,31 +16,54 @@ export function registerExtractorHandlers(): void {
let authService: ErpAuthService | null = null let authService: ErpAuthService | null = null
try { try {
// Check environment variables
const erpUrl = process.env.ERP_URL || ''
const erpUsername = process.env.ERP_USERNAME || ''
const erpPassword = process.env.ERP_PASSWORD || ''
console.log('[Extractor] Config:', {
url: erpUrl ? '***' : 'EMPTY',
username: erpUsername ? '***' : 'EMPTY'
})
if (!erpUrl || !erpUsername || !erpPassword) {
throw new Error(
'ERP 配置不完整。请检查 .env 文件中的 ERP_URL, ERP_USERNAME, ERP_PASSWORD'
)
}
// Create auth service and login // Create auth service and login
authService = new ErpAuthService({ authService = new ErpAuthService({
url: process.env.ERP_URL || '', url: erpUrl,
username: process.env.ERP_USERNAME || '', username: erpUsername,
password: process.env.ERP_PASSWORD || '', password: erpPassword,
headless: true headless: true
}) })
console.log('[Extractor] Logging in to ERP...')
await authService.login() await authService.login()
console.log('[Extractor] Login successful')
// Create extractor service and run extraction // Create extractor service and run extraction
const extractor = new ExtractorService(authService) const extractor = new ExtractorService(authService)
console.log('[Extractor] Starting extraction for orders:', input.orderNumbers)
const result = await extractor.extract(input) const result = await extractor.extract(input)
console.log('[Extractor] Extraction completed:', result)
return { success: true, data: result } return { success: true, data: result }
} catch (error) { } catch (error) {
const message = error instanceof Error ? error.message : 'Unknown error' const message = error instanceof Error ? error.message : 'Unknown error'
return { success: false, error: message } console.error('[Extractor] Error:', message)
console.error('[Extractor] Stack:', error instanceof Error ? error.stack : 'N/A')
return { success: false, error: `提取失败:${message}` }
} finally { } finally {
// Clean up: close browser // Clean up: close browser
if (authService) { if (authService) {
try { try {
await authService.close() await authService.close()
} catch { console.log('[Extractor] Browser closed')
// Ignore cleanup errors } catch (closeError) {
console.warn('[Extractor] Error closing browser:', closeError)
} }
} }
} }

View File

@@ -124,7 +124,10 @@ export const ExtractorPage: React.FC = () => {
{error && ( {error && (
<div className="error-section"> <div className="error-section">
<h3></h3> <h3></h3>
<p>{error}</p> <div className="error-message" title="双击可选中复制">
{error}
</div>
<p className="error-hint">💡 </p>
</div> </div>
)} )}
@@ -286,9 +289,27 @@ export const ExtractorPage: React.FC = () => {
margin: 0 0 8px 0; margin: 0 0 8px 0;
font-size: 16px; font-size: 16px;
} }
.error-section p { .error-message {
color: #666; background: #fff;
margin: 0; padding: 12px;
border-radius: 4px;
font-family: 'Consolas', 'Monaco', monospace;
font-size: 13px;
color: #333;
border: 1px solid #ffccc7;
user-select: text;
-webkit-user-select: text;
cursor: text;
white-space: pre-wrap;
word-break: break-all;
}
.error-message:hover {
background: #fffbfc;
}
.error-hint {
color: #999;
font-size: 12px;
margin: 8px 0 0 0;
} }
.result-section { .result-section {
margin-top: 24px; margin-top: 24px;