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:
@@ -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.
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user