optimize: 捕获DS的各种未知异常,并将异常信息记录到日志文件中。

pull/445/head
王良 2025-01-27 09:41:57 +08:00
parent 1a92762f82
commit fe060ebfa7
8 changed files with 72 additions and 37 deletions

View File

@ -4,10 +4,6 @@ const log = require('./utils/util.log')
// 避免异常崩溃 // 避免异常崩溃
process.on('uncaughtException', (err) => { process.on('uncaughtException', (err) => {
if (err.code === 'ECONNABORTED') {
// console.error(err.errno)
return
}
log.error('Process Uncaught Exception:', err) log.error('Process Uncaught Exception:', err)
}) })

View File

@ -93,7 +93,7 @@ function setTray () {
click: () => { click: () => {
log.info('force quit') log.info('force quit')
forceClose = true forceClose = true
quit() quit('系统托盘图标-退出')
}, },
}, },
] ]
@ -112,12 +112,12 @@ function setTray () {
// 当桌面主题更新时 // 当桌面主题更新时
if (isMac) { if (isMac) {
nativeTheme.on('updated', () => { nativeTheme.on('updated', () => {
console.log('i am changed') log.info('i am changed')
if (nativeTheme.shouldUseDarkColors) { if (nativeTheme.shouldUseDarkColors) {
console.log('i am dark.') log.info('i am dark.')
tray.setImage(iconWhitePath) tray.setImage(iconWhitePath)
} else { } else {
console.log('i am light.') log.info('i am light.')
tray.setImage(iconBlackPath) tray.setImage(iconBlackPath)
// tray.setPressedImage(iconWhitePath) // tray.setPressedImage(iconWhitePath)
} }
@ -149,10 +149,10 @@ function isLinux () {
return platform === 'linux' return platform === 'linux'
} }
function hideWin () { function hideWin (reason = '') {
if (win) { if (win) {
if (isLinux()) { if (isLinux()) {
quit() quit(`is linux, not hide win, do quit, ${reason}`)
return return
} }
win.hide() win.hide()
@ -160,12 +160,16 @@ function hideWin () {
app.dock.hide() app.dock.hide()
} }
winIsHidden = true winIsHidden = true
} else {
log.warn('win is null, do not hide win')
} }
} }
function showWin () { function showWin () {
if (win) { if (win) {
win.show() win.show()
} else {
log.warn('win is null, do not show win')
} }
if (app.dock) { if (app.dock) {
app.dock.show() app.dock.show()
@ -204,7 +208,7 @@ function createWindow (startHideWindow, autoQuitIfError = true) {
log.error('创建窗口失败:', e) log.error('创建窗口失败:', e)
dialog.showErrorBox('错误', `创建窗口失败: ${e.message}`) dialog.showErrorBox('错误', `创建窗口失败: ${e.message}`)
if (autoQuitIfError) { if (autoQuitIfError) {
quit() quit('创建窗口失败')
} }
return false return false
} }
@ -231,7 +235,7 @@ function createWindow (startHideWindow, autoQuitIfError = true) {
} }
if (startHideWindow) { if (startHideWindow) {
hideWin() hideWin('startHideWindow')
} }
win.on('closed', async (...args) => { win.on('closed', async (...args) => {
@ -242,9 +246,9 @@ function createWindow (startHideWindow, autoQuitIfError = true) {
ipcMain.on('close', async (event, message) => { ipcMain.on('close', async (event, message) => {
if (message.value === 1) { if (message.value === 1) {
quit() quit('ipc receive "close"')
} else { } else {
hideWin() hideWin('ipc receive "close"')
} }
}) })
@ -255,7 +259,7 @@ function createWindow (startHideWindow, autoQuitIfError = true) {
} }
e.preventDefault() e.preventDefault()
if (isLinux()) { if (isLinux()) {
quit() quit('win close')
return return
} }
const config = DevSidecar.api.config.get() const config = DevSidecar.api.config.get()
@ -265,16 +269,16 @@ function createWindow (startHideWindow, autoQuitIfError = true) {
win.webContents.send('close.showTip', closeStrategy) win.webContents.send('close.showTip', closeStrategy)
} else if (closeStrategy === 1) { } else if (closeStrategy === 1) {
// 直接退出 // 直接退出
quit() quit('win close')
} else if (closeStrategy === 2) { } else if (closeStrategy === 2) {
// 隐藏窗口 // 隐藏窗口
hideWin() hideWin('win close')
} }
}) })
win.on('session-end', async (e, ...args) => { win.on('session-end', async (e, ...args) => {
log.info('win session-end:', e, ...args) log.info('win session-end:', e, ...args)
await quit() await quit('win session-end')
}) })
const shortcut = (event, input) => { const shortcut = (event, input) => {
@ -302,7 +306,7 @@ function createWindow (startHideWindow, autoQuitIfError = true) {
} }
win.webContents.executeJavaScript('config') win.webContents.executeJavaScript('config')
.then((value) => { .then((value) => {
console.info('window.config:', value, ', key:', input.key) log.info('window.config:', value, ', key:', input.key)
if (!value || (value.disableBeforeInputEvent !== true && value.disableBeforeInputEvent !== 'true')) { if (!value || (value.disableBeforeInputEvent !== true && value.disableBeforeInputEvent !== 'true')) {
shortcut(event, input) shortcut(event, input)
} }
@ -315,6 +319,14 @@ function createWindow (startHideWindow, autoQuitIfError = true) {
// 监听渲染进程发送过来的消息 // 监听渲染进程发送过来的消息
win.webContents.on('ipc-message', (event, channel, message, ...args) => { win.webContents.on('ipc-message', (event, channel, message, ...args) => {
console.info('win ipc-message:', event, channel, message, ...args) console.info('win ipc-message:', event, channel, message, ...args)
// 记录日志
if (channel && channel.startsWith('[ERROR]')) {
log.error('win ipc-message:', channel.substring(7), message, ...args)
} else {
log.info('win ipc-message:', channel, message, ...args)
}
if (channel === 'change-showHideShortcut') { if (channel === 'change-showHideShortcut') {
registerShowHideShortcut(message) registerShowHideShortcut(message)
} }
@ -324,9 +336,12 @@ function createWindow (startHideWindow, autoQuitIfError = true) {
} }
async function beforeQuit () { async function beforeQuit () {
log.info('before quit')
return DevSidecar.api.shutdown() return DevSidecar.api.shutdown()
} }
async function quit () { async function quit (reason) {
log.info('app quit:', reason)
if (tray) { if (tray) {
tray.displayBalloon({ title: '正在关闭', content: '关闭中,请稍候。。。' }) tray.displayBalloon({ title: '正在关闭', content: '关闭中,请稍候。。。' })
} }
@ -404,7 +419,7 @@ try {
// 禁止双开 // 禁止双开
const isFirstInstance = app.requestSingleInstanceLock() const isFirstInstance = app.requestSingleInstanceLock()
if (!isFirstInstance) { if (!isFirstInstance) {
log.info('is second instance') log.info('app quit: is second instance')
setTimeout(() => { setTimeout(() => {
app.quit() app.quit()
}, 1000) }, 1000)
@ -412,7 +427,7 @@ try {
app.on('before-quit', async () => { app.on('before-quit', async () => {
log.info('before-quit') log.info('before-quit')
if (process.platform === 'darwin') { if (process.platform === 'darwin') {
quit() quit('before quit')
} }
}) })
app.on('will-quit', () => { app.on('will-quit', () => {
@ -433,7 +448,7 @@ try {
// On macOS it is common for applications and their menu bar // On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q // to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') { if (process.platform !== 'darwin') {
quit() quit('window-all-closed')
} }
}) })
@ -489,7 +504,7 @@ try {
e.preventDefault() e.preventDefault()
} }
log.info('系统关机,恢复代理设置') log.info('系统关机,恢复代理设置')
await quit() await quit('系统关机')
}) })
}) })
} }
@ -501,19 +516,18 @@ try {
if (process.platform === 'win32') { if (process.platform === 'win32') {
process.on('message', (data) => { process.on('message', (data) => {
if (data === 'graceful-exit') { if (data === 'graceful-exit') {
quit() quit('graceful-exit')
} }
}) })
} else { } else {
process.on('SIGINT', () => { process.on('SIGINT', () => {
quit() quit('SIGINT')
}) })
} }
} }
// 系统关机和重启时的操作 // 系统关机和重启时的操作
process.on('exit', () => { process.on('exit', () => {
log.info('进程结束退出app') quit('进程结束退出app')
quit()
}) })
log.info('background.js finished') log.info('background.js finished')

View File

@ -3,6 +3,7 @@ import autoStart from './auto-start/backend'
import fileSelector from './file-selector/backend' import fileSelector from './file-selector/backend'
import tongji from './tongji/backend' import tongji from './tongji/backend'
import update from './update/backend' import update from './update/backend'
import log from '../utils/util.log'
const modules = { const modules = {
api, // 核心接口模块 api, // 核心接口模块
@ -14,7 +15,7 @@ const modules = {
export default { export default {
install (context) { install (context) {
for (const module in modules) { for (const module in modules) {
console.log('install', module) log.info('install module:', module)
modules[module].install(context) modules[module].install(context)
} }
}, },

View File

@ -1,6 +1,7 @@
import antd from 'ant-design-vue' import antd from 'ant-design-vue'
import Vue from 'vue' import Vue from 'vue'
import VueRouter from 'vue-router' import VueRouter from 'vue-router'
import { ipcRenderer } from 'electron'
import view from './view' import view from './view'
import App from './view/App.vue' import App from './view/App.vue'
import DsContainer from './view/components/container' import DsContainer from './view/components/container'
@ -25,9 +26,14 @@ try {
}) })
view.initApi(app).then(async (api) => { view.initApi(app).then(async (api) => {
// 初始化status // 初始化status
try {
await view.initPre(Vue, api) await view.initPre(Vue, api)
app.$mount('#app') app.$mount('#app')
view.initModules(app, router) view.initModules(app, router)
} catch (e) {
console.error('view初始化出现未知异常', e)
ipcRenderer.send('view初始化出现未知异常', e)
}
}) })
// fix vue-router NavigationDuplicated // fix vue-router NavigationDuplicated
@ -41,6 +47,16 @@ try {
} }
console.info('main.js finished') console.info('main.js finished')
ipcRenderer.send('main.js finished')
} catch (e) { } catch (e) {
console.error('页面加载出现未知异常:', e) console.error('页面加载出现未知异常:', e)
ipcRenderer.send('[ERROR] 页面加载出现未知异常:', e)
}
try {
window.onerror = (message, source, lineno, colno, error) => {
ipcRenderer.send(`[ERROR] JavaScript脚本异常Error in ${source} at line ${lineno}: ${message}`, error)
}
} catch (e) {
console.error('监听 window.onerror 出现异常:', e)
} }

View File

@ -1 +1,9 @@
window.ipcRenderer = require('electron').ipcRenderer try {
window.ipcRenderer = require('electron').ipcRenderer
window.onerror = (message, source, lineno, colno, error) => {
window.ipcRenderer.send(`[ERROR] JavaScript脚本异常Error in ${source} at line ${lineno}: ${message}`, error)
}
} catch (e) {
console.error('load electron.ipcRenderer error:', e)
}

View File

@ -112,7 +112,7 @@ function registerProcessListener () {
log.info('代理服务进程被关闭:', code, signal) log.info('代理服务进程被关闭:', code, signal)
}) })
process.on('beforeExit', (code, signal) => { process.on('beforeExit', (code, signal) => {
console.log('Process beforeExit event with code: ', code, signal) log.info('Process beforeExit event with code: ', code, signal)
}) })
process.on('SIGPIPE', (code, signal) => { process.on('SIGPIPE', (code, signal) => {
log.warn('sub Process SIGPIPE', code, signal) log.warn('sub Process SIGPIPE', code, signal)

View File

@ -160,7 +160,7 @@ module.exports = function createRequestHandler (createIntercepts, middlewares, e
} else { } else {
log.info(`请求返回: 【${proxyRes.statusCode}${url}, cost: ${cost} ms`) log.info(`请求返回: 【${proxyRes.statusCode}${url}, cost: ${cost} ms`)
} }
// console.log('request:', proxyReq, proxyReq.socket) // log.info('request:', proxyReq, proxyReq.socket)
if (cost > MAX_SLOW_TIME) { if (cost > MAX_SLOW_TIME) {
countSlow(isDnsIntercept, `代理请求成功但太慢, cost: ${cost} ms > ${MAX_SLOW_TIME} ms`) countSlow(isDnsIntercept, `代理请求成功但太慢, cost: ${cost} ms > ${MAX_SLOW_TIME} ms`)
@ -246,7 +246,7 @@ module.exports = function createRequestHandler (createIntercepts, middlewares, e
const proxyRes = await proxyRequestPromise() const proxyRes = await proxyRequestPromise()
// proxyRes.on('data', (chunk) => { // proxyRes.on('data', (chunk) => {
// // console.log('BODY: ') // // log.info('BODY: ')
// }) // })
proxyRes.on('error', (error) => { proxyRes.on('error', (error) => {
countSlow(null, `error: ${error.message}`) countSlow(null, `error: ${error.message}`)

View File

@ -15,7 +15,7 @@ const pki = forge.pki
// const user = os.userInfo() // const user = os.userInfo()
// username = user.username // username = user.username
// } catch (e) { // } catch (e) {
// console.log('get userinfo error', e) // log.info('get userinfo error', e)
// } // }
utils.createCA = function (CN) { utils.createCA = function (CN) {