diff --git a/app.go b/app.go
index e589f58..50ce81b 100644
--- a/app.go
+++ b/app.go
@@ -41,6 +41,10 @@ func NewApp() *App {
// startup is called at application startup
func (a *App) startup(ctx context.Context) {
+ defer PanicHandler()
+ runtime.EventsOn(ctx, "frontendError", func(optionalData ...interface{}) {
+ logger.SugaredLogger.Errorf("Frontend error: %v\n", optionalData)
+ })
logger.SugaredLogger.Infof("Version:%s", Version)
// Perform your setup here
a.ctx = ctx
@@ -86,6 +90,8 @@ func checkUpdate(a *App) {
// domReady is called after front-end resources have been loaded
func (a *App) domReady(ctx context.Context) {
+ defer PanicHandler()
+
// Add your action here
//定时更新数据
go func() {
@@ -321,6 +327,7 @@ func addStockFollowData(follow data.FollowedStock, stockData *data.StockInfo) {
// either by clicking the window close button or calling runtime.Quit.
// Returning true will cause the application to continue, false will continue shutdown as normal.
func (a *App) beforeClose(ctx context.Context) (prevent bool) {
+ defer PanicHandler()
dialog, err := runtime.MessageDialog(ctx, runtime.MessageDialogOptions{
Type: runtime.QuestionDialog,
@@ -344,6 +351,7 @@ func (a *App) beforeClose(ctx context.Context) (prevent bool) {
// shutdown is called at application termination
func (a *App) shutdown(ctx context.Context) {
+ defer PanicHandler()
// Perform your teardown here
systray.Quit()
}
diff --git a/backend/data/openai_api.go b/backend/data/openai_api.go
index 11583e5..8124115 100644
--- a/backend/data/openai_api.go
+++ b/backend/data/openai_api.go
@@ -76,7 +76,19 @@ type AiResponse struct {
func (o OpenAi) NewChatStream(stock, stockCode string) <-chan string {
ch := make(chan string, 512)
+
+ defer func() {
+ if err := recover(); err != nil {
+ logger.SugaredLogger.Error("NewChatStream panic", err)
+ }
+ }()
+
go func() {
+ defer func() {
+ if err := recover(); err != nil {
+ logger.SugaredLogger.Error("NewChatStream goroutine panic", err)
+ }
+ }()
defer close(ch)
msg := []map[string]interface{}{
{
@@ -174,7 +186,7 @@ func (o OpenAi) NewChatStream(stock, stockCode string) <-chan string {
client.SetBaseURL(o.BaseUrl)
client.SetHeader("Authorization", "Bearer "+o.ApiKey)
client.SetHeader("Content-Type", "application/json")
- client.SetRetryCount(3)
+ //client.SetRetryCount(3)
if o.TimeOut <= 0 {
o.TimeOut = 300
}
@@ -190,14 +202,15 @@ func (o OpenAi) NewChatStream(stock, stockCode string) <-chan string {
}).
Post("/chat/completions")
- defer resp.RawBody().Close()
+ body := resp.RawBody()
+ defer body.Close()
if err != nil {
logger.SugaredLogger.Infof("Stream error : %s", err.Error())
ch <- err.Error()
return
}
- scanner := bufio.NewScanner(resp.RawBody())
+ scanner := bufio.NewScanner(body)
for scanner.Scan() {
line := scanner.Text()
logger.SugaredLogger.Infof("Received data: %s", line)
@@ -232,8 +245,13 @@ func (o OpenAi) NewChatStream(stock, stockCode string) <-chan string {
}
}
} else {
- logger.SugaredLogger.Infof("Stream data error : %s", err.Error())
- ch <- err.Error()
+ if err != nil {
+ logger.SugaredLogger.Infof("Stream data error : %s", err.Error())
+ ch <- err.Error()
+ } else {
+ logger.SugaredLogger.Infof("Stream data error : %s", data)
+ ch <- data
+ }
}
} else {
ch <- line
diff --git a/frontend/src/App.vue b/frontend/src/App.vue
index ad4b884..cbb7fd9 100644
--- a/frontend/src/App.vue
+++ b/frontend/src/App.vue
@@ -1,6 +1,7 @@
diff --git a/frontend/src/components/settings.vue b/frontend/src/components/settings.vue
index 59f833d..a21b879 100644
--- a/frontend/src/components/settings.vue
+++ b/frontend/src/components/settings.vue
@@ -4,6 +4,7 @@ import {onMounted, ref, watch} from "vue";
import {ExportConfig, GetConfig, SendDingDingMessageByType, UpdateConfig} from "../../wailsjs/go/main/App";
import {useMessage} from "naive-ui";
import {data} from "../../wailsjs/go/models";
+import {EventsEmit} from "../../wailsjs/runtime";
const message = useMessage()
const formRef = ref(null)
@@ -150,6 +151,19 @@ function importConfig(){
};
input.click();
}
+
+
+window.onerror = function (message, source, lineno, colno, error) {
+ // 将错误信息发送给后端
+ EventsEmit("frontendError", {
+ message: message,
+ source: source,
+ lineno: lineno,
+ colno: colno,
+ error: error ? error.stack : null
+ });
+ return true;
+};
diff --git a/frontend/src/components/stock.vue b/frontend/src/components/stock.vue
index d983cd1..c9f57da 100644
--- a/frontend/src/components/stock.vue
+++ b/frontend/src/components/stock.vue
@@ -22,7 +22,7 @@ import {
useModal,
useNotification
} from 'naive-ui'
-import {EventsOn, WindowFullscreen, WindowReload, WindowUnfullscreen} from '../../wailsjs/runtime'
+import {EventsEmit, EventsOn, WindowFullscreen, WindowReload, WindowUnfullscreen} from '../../wailsjs/runtime'
import {Add, Search,StarOutline} from '@vicons/ionicons5'
import { MdPreview } from 'md-editor-v3';
// preview.css相比style.css少了编辑器那部分样式
@@ -546,7 +546,17 @@ function getHeight() {
return document.documentElement.clientHeight
}
-
+window.onerror = function (message, source, lineno, colno, error) {
+ // 将错误信息发送给后端
+ EventsEmit("frontendError", {
+ message: message,
+ source: source,
+ lineno: lineno,
+ colno: colno,
+ error: error ? error.stack : null
+ });
+ return true;
+};
diff --git a/main.go b/main.go
index 849b547..4740804 100644
--- a/main.go
+++ b/main.go
@@ -3,6 +3,7 @@ package main
import (
"embed"
"encoding/json"
+ "fmt"
"github.com/duke-git/lancet/v2/convertor"
"github.com/wailsapp/wails/v2"
"github.com/wailsapp/wails/v2/pkg/logger"
@@ -18,6 +19,7 @@ import (
"log"
"os"
goruntime "runtime"
+ "runtime/debug"
"time"
)
@@ -206,3 +208,11 @@ func checkDir(dir string) {
logger.NewDefaultLogger().Info("create dir: " + dir)
}
}
+
+// PanicHandler 捕获 panic 的包装函数
+func PanicHandler() {
+ if r := recover(); r != nil {
+ fmt.Printf("Recovered from panic: %v\n", r)
+ debug.PrintStack()
+ }
+}