mirror of
https://github.com/ArvinLovegood/go-stock.git
synced 2025-07-19 00:00:09 +08:00
feat(frontend):增加前端错误捕获和后端panic处理
- 在前端 App.vue、settings.vue 和 stock.vue 中添加 window.onerror 事件处理器,捕获前端错误并发送给后端 - 在后端 app.go 和 openai_api.go 中添加 panic 处理逻辑,捕获并记录 panic错误 - 在 main.go 中添加 PanicHandler 函数,用于捕获和处理全局 panic
This commit is contained in:
parent
22111411c3
commit
b4c55ce233
8
app.go
8
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()
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -1,6 +1,7 @@
|
||||
<script setup>
|
||||
import stockInfo from './components/stock.vue'
|
||||
import {
|
||||
EventsEmit,
|
||||
EventsOn,
|
||||
Quit,
|
||||
WindowFullscreen, WindowGetPosition,
|
||||
@ -157,6 +158,18 @@ EventsOn("realtime_profit",(data)=>{
|
||||
EventsOn("telegraph",(data)=>{
|
||||
telegraph.value=data
|
||||
})
|
||||
|
||||
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;
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -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;
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
10
main.go
10
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()
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user