Skip to content

Commit ac0a258

Browse files
committed
chore: 前端统一错误处理
1 parent cd14b60 commit ac0a258

11 files changed

Lines changed: 114 additions & 31 deletions

File tree

MaiChartManager/Front/src/App.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { defineComponent } from 'vue';
22
import { dateZhCN, NConfigProvider, NDialogProvider, NMessageProvider, NNotificationProvider, zhCN } from 'naive-ui';
33
import { RouterView } from 'vue-router';
4+
import FeedbackErrorDialog from "@/components/FeedbackErrorDialog";
45

56
export default defineComponent({
67
render() {
@@ -10,6 +11,7 @@ export default defineComponent({
1011
<NDialogProvider>
1112
<NMessageProvider>
1213
<RouterView/>
14+
<FeedbackErrorDialog/>
1315
</NMessageProvider>
1416
</NDialogProvider>
1517
</NNotificationProvider>

MaiChartManager/Front/src/client/api.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ export default (new Api({
44
baseApiParams: {
55
headers: {
66
accept: 'application/json',
7-
}
8-
}
7+
},
8+
},
99
})).maiChartManagerServlet
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { computed, defineComponent, ref, watch } from "vue";
2+
import { NButton, NFlex, NFormItem, NInput, NModal, useMessage } from "naive-ui";
3+
import { error, errorContext, errorId } from "@/store/refs";
4+
import { captureFeedback } from "@sentry/vue";
5+
6+
export default defineComponent({
7+
setup(props) {
8+
const nMessage = useMessage();
9+
10+
const message = computed(() => {
11+
if (!error.value) return "";
12+
if (error.value.error) {
13+
return error.value.error.message || error.value.error.toString();
14+
}
15+
if (error.value.message) {
16+
return error.value.message;
17+
}
18+
return error.value.toString();
19+
})
20+
21+
const userInput = ref("");
22+
23+
watch(() => error.value, (v, old) => {
24+
// 防止输入到一半出另一个错误清空输入
25+
if (old) return;
26+
userInput.value = "";
27+
});
28+
29+
const report = () => {
30+
captureFeedback({
31+
associatedEventId: errorId.value,
32+
message: userInput.value || "无",
33+
})
34+
nMessage.success("感谢大佬的反馈!");
35+
error.value = null;
36+
}
37+
38+
return () => <NModal
39+
preset="card"
40+
class="w-[min(50vw,60em)]"
41+
title="出错了!"
42+
show={!!error.value}
43+
onUpdateShow={() => error.value = null}
44+
>
45+
{{
46+
default: () => <NFlex vertical size="large">
47+
<div class="text-lg">{errorContext.value}</div>
48+
{message.value}
49+
<NInput v-model:value={userInput.value} class="w-full" type="textarea" placeholder="可以提供一下相关背景和上下文吗?比如说你的游戏或者乐曲有没有什么特别之处"/>
50+
</NFlex>,
51+
footer: () => <NFlex justify="end">
52+
<NButton onClick={report}>发送反馈</NButton>
53+
</NFlex>
54+
}}
55+
</NModal>;
56+
}
57+
})

MaiChartManager/Front/src/components/ImportChartButton/index.tsx

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ import SelectFileTypeTip from "@/components/ImportChartButton/SelectFileTypeTip"
44
import { ImportChartMessage, MessageLevel } from "@/client/apiGen";
55
import CheckingModal from "@/components/ImportChartButton/CheckingModal";
66
import api from "@/client/api";
7-
import { musicList, selectMusicId, updateMusicList } from "@/store/refs";
7+
import { globalCapture, musicList, selectMusicId, updateMusicList } from "@/store/refs";
88
import ErrorDisplayIdInput from "@/components/ImportChartButton/ErrorDisplayIdInput";
99
import ImportStepDisplay from "@/components/ImportChartButton/ImportStepDisplay";
1010
import { useStorage } from "@vueuse/core";
11+
import { captureException } from "@sentry/vue";
1112

1213
enum STEP {
1314
none,
@@ -151,6 +152,12 @@ export default defineComponent({
151152
music.importStep = IMPORT_STEP.finish;
152153
} catch (e: any) {
153154
console.log(music, e)
155+
captureException(e.error || e, {
156+
tags: {
157+
context: '导入乐曲出错',
158+
step: music.importStep,
159+
}
160+
})
154161
errors.value.push({level: MessageLevel.Fatal, message: e.error?.message || e.message || e.toString(), name: music.name});
155162
try {
156163
await api.DeleteMusic(music.id);
@@ -217,10 +224,7 @@ export default defineComponent({
217224
} catch (e: any) {
218225
if (e.name === 'AbortError') return
219226
console.log(e)
220-
dialog.error({
221-
title: '错误',
222-
content: e.message,
223-
})
227+
globalCapture(e, "导入乐曲出错(全局)")
224228
} finally {
225229
if (step.value !== STEP.showResultError)
226230
step.value = STEP.none

MaiChartManager/Front/src/components/ModManager/ConfigEditor.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import comments from './modComments.yaml';
55
import api from "@/client/api";
66
import { capitalCase } from "change-case";
77
import ProblemsDisplay from "@/components/ProblemsDisplay";
8+
import { globalCapture } from "@/store/refs";
89

910
export default defineComponent({
1011
props: {
@@ -40,7 +41,7 @@ export default defineComponent({
4041
await api.InstallMelonLoader()
4142
await props.refresh()
4243
} catch (e: any) {
43-
dialog.error({title: '安装失败', content: e.toString()})
44+
globalCapture(e, "安装 MelonLoader 失败")
4445
} finally {
4546
installingMelonLoader.value = false
4647
}
@@ -56,7 +57,7 @@ export default defineComponent({
5657
showAquaMaiInstallDone.value = true
5758
setTimeout(() => showAquaMaiInstallDone.value = false, 3000);
5859
} catch (e: any) {
59-
dialog.error({title: '安装失败', content: e.toString()})
60+
globalCapture(e, "安装 AquaMai 失败")
6061
} finally {
6162
installingAquaMai.value = false
6263
}

MaiChartManager/Front/src/components/MusicEdit/AcbAwb.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { computed, defineComponent, PropType, ref } from "vue";
22
import { HttpResponse, MusicXmlWithABJacket } from "@/client/apiGen";
33
import { NButton, NDrawer, NDrawerContent, NFlex, NForm, NFormItem, NInputNumber, NModal, NRadio, useDialog } from "naive-ui";
44
import noJacket from "@/assets/noJacket.webp";
5-
import { selectedADir } from "@/store/refs";
5+
import { globalCapture, selectedADir } from "@/store/refs";
66
import FileTypeIcon from "@/components/FileTypeIcon";
77
import stdIcon from "@/assets/stdIcon.png";
88
import dxIcon from "@/assets/dxIcon.png";
@@ -84,10 +84,7 @@ export default defineComponent({
8484
} catch (e: any) {
8585
if (e.name === 'AbortError') return
8686
console.log(e)
87-
dialog.error({
88-
title: '错误',
89-
content: e.message,
90-
})
87+
globalCapture(e, "导入音频出错")
9188
} finally {
9289
tipShow.value = false;
9390
tipSelectAwbShow.value = false;

MaiChartManager/Front/src/components/MusicEdit/JacketBox.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { computed, defineComponent, PropType, ref } from "vue";
22
import noJacket from "@/assets/noJacket.webp";
33
import api from "@/client/api";
44
import { useDialog } from "naive-ui";
5-
import { selectedMusicBrief } from "@/store/refs";
5+
import { globalCapture, selectedMusicBrief } from "@/store/refs";
66
import { MusicXmlWithABJacket } from "@/client/apiGen";
77

88
export default defineComponent({
@@ -52,10 +52,7 @@ export default defineComponent({
5252
} catch (e: any) {
5353
if (e.name === 'AbortError') return
5454
console.log(e)
55-
dialog.error({
56-
title: '错误',
57-
content: e.message,
58-
})
55+
globalCapture(e, "替换图片失败")
5956
}
6057
}
6158

MaiChartManager/Front/src/components/MusicEdit/index.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { computed, defineComponent, onMounted, PropType, ref, watch } from "vue";
22
import { Chart, GenreXml, MusicXmlWithABJacket } from "@/client/apiGen";
3-
import { addVersionList, genreList, selectedADir, selectedMusicBrief, selectMusicId, updateAddVersionList, updateGenreList, updateMusicList } from "@/store/refs";
3+
import { addVersionList, genreList, globalCapture, selectedADir, selectedMusicBrief, selectMusicId, updateAddVersionList, updateGenreList, updateMusicList } from "@/store/refs";
44
import api from "@/client/api";
55
import { NButton, NFlex, NForm, NFormItem, NInput, NInputNumber, NSelect, NTabPane, NTabs, SelectOption, useDialog, useMessage } from "naive-ui";
66
import JacketBox from "./JacketBox";
@@ -35,8 +35,7 @@ const Component = defineComponent({
3535
selectedLevel.value = firstEnabledChart;
3636
}
3737
} catch (e: any) {
38-
message.error('加载歌曲信息失败');
39-
captureException(e.error || e);
38+
globalCapture(e, "获取乐曲详情失败")
4039
}
4140

4241
watch(() => info.value?.name, sync('name', api.EditMusicName));

MaiChartManager/Front/src/plugins/sentry.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export default {
1515
// Tracing
1616
tracesSampleRate: 1.0, // Capture 100% of the transactions
1717
// Session Replay
18-
replaysSessionSampleRate: 0.1, // This sets the sample rate at 10%. You may want to change it to 100% while in development and then sample at a lower rate in production.
18+
replaysSessionSampleRate: 0.5, // This sets the sample rate at 10%. You may want to change it to 100% while in development and then sample at a lower rate in production.
1919
replaysOnErrorSampleRate: 1.0, // If you're not already sampling the entire session, change the sample rate to 100% when sampling sessions where errors occur.
2020
// Profiling
2121
profilesSampleRate: 1.0, // Profile 100% of the transactions. This value is relative to tracesSampleRate

MaiChartManager/Front/src/store/refs.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,21 @@
11
import { computed, ref } from "vue";
22
import { AppVersionResult, GenreXml, MusicBrief, VersionXml } from "@/client/apiGen";
33
import api from "@/client/api";
4+
import { captureException } from "@sentry/vue";
5+
6+
export const error = ref();
7+
export const errorId = ref<string>();
8+
export const errorContext = ref<string>();
9+
10+
export const globalCapture = (err: any, context: string) => {
11+
error.value = err;
12+
errorContext.value = context;
13+
errorId.value = captureException(err.error || err, {
14+
tags: {
15+
context
16+
}
17+
})
18+
}
419

520
export const selectMusicId = ref(0)
621
export const genreList = ref<GenreXml[]>([]);

0 commit comments

Comments
 (0)