diff --git a/src/main/apis/app/uploader/index.ts b/src/main/apis/app/uploader/index.ts index 9beb95c2e..01faafdaf 100644 --- a/src/main/apis/app/uploader/index.ts +++ b/src/main/apis/app/uploader/index.ts @@ -13,6 +13,7 @@ import util from 'util' import { IPicGo } from 'picgo/dist/src/types' import { showNotification, calcDurationRange } from '~/main/utils/common' import { TALKING_DATA_EVENT } from '~/universal/events/constants' +import logger from '@core/picgo/logger' const waitForShow = (webcontent: WebContents) => { return new Promise((resolve, reject) => { @@ -107,7 +108,7 @@ class Uploader { return this } - upload (img?: IUploadOption): Promise { + async upload (img?: IUploadOption): Promise { if (this.uploading) { showNotification({ title: '上传失败', @@ -115,47 +116,36 @@ class Uploader { }) return Promise.resolve(false) } - return new Promise((resolve) => { - try { - const startTime = Date.now() - this.uploading = true - picgo.upload(img) - picgo.once('finished', ctx => { - this.uploading = false - if (ctx.output.every((item: ImgInfo) => item.imgUrl)) { - if (this.webContents) { - handleTalkingData(this.webContents, { - fromClipboard: !img, - type: db.get('picBed.current') || 'smms', - count: img ? img.length : 1, - duration: Date.now() - startTime - } as IAnalyticsData) - } - resolve(ctx.output) - } else { - resolve(false) - } - picgo.removeAllListeners('failed') - }) - picgo.once('failed', (e: Error) => { - this.uploading = false - setTimeout(() => { - showNotification({ - title: '上传失败', - body: util.format(e.stack), - clickToCopy: true - }) - }, 500) - picgo.removeAllListeners('finished') - resolve(false) - }) - } catch (e) { - this.uploading = false - picgo.removeAllListeners('failed') - picgo.removeAllListeners('finished') - resolve([]) + try { + const startTime = Date.now() + this.uploading = true + const output = await picgo.upload(img) + this.uploading = false + if (Array.isArray(output) && output.every((item: ImgInfo) => item.imgUrl)) { + if (this.webContents) { + handleTalkingData(this.webContents, { + fromClipboard: !img, + type: db.get('picBed.current') || 'smms', + count: img ? img.length : 1, + duration: Date.now() - startTime + } as IAnalyticsData) + } + return output + } else { + return false } - }) + } catch (e) { + this.uploading = false + logger.error(e) + setTimeout(() => { + showNotification({ + title: '上传失败', + body: util.format(e.stack), + clickToCopy: true + }) + }, 500) + return false + } } } diff --git a/src/main/lifeCycle/errorHandler.ts b/src/main/lifeCycle/errorHandler.ts new file mode 100644 index 000000000..3fa9ca83d --- /dev/null +++ b/src/main/lifeCycle/errorHandler.ts @@ -0,0 +1,33 @@ +import { app } from 'electron' +import fse from 'fs-extra' +import path from 'path' +import dayjs from 'dayjs' +import util from 'util' +const STORE_PATH = app.getPath('userData') +const LOG_PATH = path.join(STORE_PATH, '/picgo.log') + +// since the error may occur in picgo-core +// so we can't use the log from picgo +const loggerWriter = (error: Error) => { + let log = `${dayjs().format('YYYY-MM-DD HH:mm:ss')} [PicGo ERROR] startup error` + if (error?.stack) { + log += `\n------Error Stack Begin------\n${util.format(error.stack)}\n-------Error Stack End-------\n` + } else { + const msg = JSON.stringify(error) + log += `${msg}\n` + } + fse.appendFileSync(LOG_PATH, log) +} + +const handleProcessError = (error: Error) => { + console.error(error) + loggerWriter(error) +} + +process.on('uncaughtException', error => { + handleProcessError(error) +}) + +process.on('unhandledRejection', (error: any) => { + handleProcessError(error) +}) diff --git a/src/main/lifeCycle/index.ts b/src/main/lifeCycle/index.ts index 511096ae9..afa51304f 100644 --- a/src/main/lifeCycle/index.ts +++ b/src/main/lifeCycle/index.ts @@ -1,3 +1,4 @@ +import './errorHandler' import { app, globalShortcut, @@ -152,13 +153,11 @@ class LifeCycle { process.on('message', data => { if (data === 'graceful-exit') { app.quit() - server.shutdown() } }) } else { process.on('SIGTERM', () => { app.quit() - server.shutdown() }) } } diff --git a/src/main/server/index.ts b/src/main/server/index.ts index d2ff3782d..11857b26b 100644 --- a/src/main/server/index.ts +++ b/src/main/server/index.ts @@ -39,6 +39,7 @@ class Server { private handleRequest = (request: http.IncomingMessage, response: http.ServerResponse) => { if (request.method === 'POST') { if (!routers.getHandler(request.url!)) { + logger.warn(`[PicGo Server] don't support [${request.url}] url`) handleResponse({ response, statusCode: 404, @@ -57,6 +58,7 @@ class Server { try { postObj = (body === '') ? {} : JSON.parse(body) } catch (err) { + logger.error(`[PicGo Server]`, err) return handleResponse({ response, body: { @@ -65,6 +67,7 @@ class Server { } }) } + logger.info(`[PicGo Server] get the request`) const handler = routers.getHandler(request.url!) handler!({ ...postObj, @@ -73,6 +76,7 @@ class Server { }) } } else { + logger.warn(`[PicGo Server] don't support [${request.method}] method`) response.statusCode = 404 response.end() } diff --git a/src/main/server/routerManager.ts b/src/main/server/routerManager.ts index bb48f0242..da6ee68b7 100644 --- a/src/main/server/routerManager.ts +++ b/src/main/server/routerManager.ts @@ -18,6 +18,7 @@ router.post('/upload', async ({ try { if (list.length === 0) { // upload with clipboard + logger.info('[PicGo Server] upload clipboard file') const res = await uploadWithClipboardFiles() if (res.success) { handleResponse({ @@ -29,10 +30,15 @@ router.post('/upload', async ({ }) } else { handleResponse({ - response + response, + body: { + success: false, + message: 'upload error' + } }) } } else { + logger.info('[PicGo Server] upload files in list') // upload with files const pathList = list.map(item => { return { @@ -50,7 +56,11 @@ router.post('/upload', async ({ }) } else { handleResponse({ - response + response, + body: { + success: false, + message: 'upload error' + } }) } } diff --git a/src/main/server/utils.ts b/src/main/server/utils.ts index bbbc2dc1d..b5009dd80 100644 --- a/src/main/server/utils.ts +++ b/src/main/server/utils.ts @@ -1,3 +1,5 @@ +import logger from '@core/picgo/logger' + export const handleResponse = ({ response, statusCode = 200, @@ -13,6 +15,9 @@ export const handleResponse = ({ header?: IObj, body?: any }) => { + if (body?.success === false) { + logger.warn('[PicGo Server] upload failed, see picgo.log for more detail ↑') + } response.writeHead(statusCode, header) response.write(JSON.stringify(body)) response.end()