vue_zhongyou 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,500 @@
1
+ <template>
2
+ <div class="test-error-page">
3
+ <div class="header">
4
+ <h2>错误捕获测试页面</h2>
5
+ <van-button
6
+ type="primary"
7
+ size="small"
8
+ @click="goToLogPage"
9
+ >
10
+ 查看错误日志
11
+ </van-button>
12
+ </div>
13
+
14
+ <!-- 统计信息 -->
15
+ <div class="stats-card">
16
+ <div class="stat-item">
17
+ <div class="stat-label">总计</div>
18
+ <div class="stat-value">{{ statistics.total }}</div>
19
+ </div>
20
+ <div class="stat-item">
21
+ <div class="stat-label">接口错误</div>
22
+ <div class="stat-value">{{ statistics.api }}</div>
23
+ </div>
24
+ <div class="stat-item">
25
+ <div class="stat-label">页面错误</div>
26
+ <div class="stat-value">{{ statistics.page }}</div>
27
+ </div>
28
+ <div class="stat-item">
29
+ <div class="stat-label">Promise错误</div>
30
+ <div class="stat-value">{{ statistics.promise }}</div>
31
+ </div>
32
+ </div>
33
+
34
+ <!-- 接口错误测试 -->
35
+ <div class="test-section">
36
+ <div class="section-title">接口错误测试</div>
37
+ <div class="button-group">
38
+ <van-button
39
+ type="primary"
40
+ :loading="loading"
41
+ @click="fetchNoticeList"
42
+ >
43
+ 正常请求(返回noticeList)
44
+ </van-button>
45
+ <van-button
46
+ type="danger"
47
+ @click="test404Error"
48
+ >
49
+ 测试404错误
50
+ </van-button>
51
+ <van-button
52
+ type="danger"
53
+ @click="test500Error"
54
+ >
55
+ 测试500错误
56
+ </van-button>
57
+ <van-button
58
+ type="warning"
59
+ @click="testNetworkError"
60
+ >
61
+ 测试网络错误
62
+ </van-button>
63
+ <van-button
64
+ type="warning"
65
+ @click="testTimeoutError"
66
+ >
67
+ 测试超时错误
68
+ </van-button>
69
+ </div>
70
+
71
+ <!-- 请求结果显示 -->
72
+ <div v-if="requestResult" class="result-box">
73
+ <div class="result-title">请求结果:</div>
74
+ <pre class="result-content">{{ requestResult }}</pre>
75
+ </div>
76
+ </div>
77
+
78
+ <!-- 页面错误测试 -->
79
+ <div class="test-section">
80
+ <div class="section-title">页面错误测试</div>
81
+ <div class="button-group">
82
+ <van-button
83
+ type="danger"
84
+ @click="testPageError"
85
+ >
86
+ 测试JavaScript错误
87
+ </van-button>
88
+ <van-button
89
+ type="danger"
90
+ @click="testReferenceError"
91
+ >
92
+ 测试引用错误
93
+ </van-button>
94
+ <van-button
95
+ type="danger"
96
+ @click="testTypeError"
97
+ >
98
+ 测试类型错误
99
+ </van-button>
100
+ </div>
101
+ </div>
102
+
103
+ <!-- Promise错误测试 -->
104
+ <div class="test-section">
105
+ <div class="section-title">Promise错误测试</div>
106
+ <div class="button-group">
107
+ <van-button
108
+ type="warning"
109
+ @click="testPromiseError"
110
+ >
111
+ 测试Promise未捕获错误
112
+ </van-button>
113
+ <van-button
114
+ type="warning"
115
+ @click="testAsyncError"
116
+ >
117
+ 测试Async函数错误
118
+ </van-button>
119
+ </div>
120
+ </div>
121
+
122
+ <!-- Vue组件错误测试 -->
123
+ <div class="test-section">
124
+ <div class="section-title">Vue组件错误测试</div>
125
+ <div class="button-group">
126
+ <van-button
127
+ type="danger"
128
+ @click="testVueError"
129
+ >
130
+ 测试Vue组件渲染错误
131
+ </van-button>
132
+ </div>
133
+ <!-- 用于触发Vue错误的组件 -->
134
+ <div v-if="shouldRenderError">
135
+ {{ undefinedVariable.property }}
136
+ </div>
137
+ </div>
138
+
139
+ <!-- 刷新统计按钮 -->
140
+ <div class="refresh-section">
141
+ <van-button
142
+ type="default"
143
+ block
144
+ @click="refreshStatistics"
145
+ >
146
+ 刷新统计信息
147
+ </van-button>
148
+ </div>
149
+ </div>
150
+ </template>
151
+
152
+ <script setup>
153
+ import { ref, onMounted } from 'vue'
154
+ import { useRouter } from 'vue-router'
155
+ import { showToast, showFailToast, showSuccessToast } from 'vant'
156
+ import request from '@/api/request'
157
+ import errorMonitor from '@/utils/errorMonitor'
158
+
159
+ const router = useRouter()
160
+ const loading = ref(false)
161
+ const requestResult = ref('')
162
+ const shouldRenderError = ref(false)
163
+ const statistics = ref({
164
+ total: 0,
165
+ api: 0,
166
+ page: 0,
167
+ promise: 0
168
+ })
169
+
170
+ // 刷新统计信息
171
+ const refreshStatistics = async () => {
172
+ try {
173
+ statistics.value = await errorMonitor.getStatistics()
174
+ showToast('统计信息已刷新')
175
+ } catch (error) {
176
+ console.error('刷新统计信息失败:', error)
177
+ showToast('刷新统计信息失败')
178
+ }
179
+ }
180
+
181
+ // 跳转到日志页面
182
+ const goToLogPage = () => {
183
+ router.push('/error-log')
184
+ }
185
+
186
+ // ============ 接口错误测试 ============
187
+
188
+ // 正常请求 - 获取noticeList
189
+ const fetchNoticeList = async () => {
190
+ loading.value = true
191
+ requestResult.value = ''
192
+
193
+ try {
194
+ // 模拟一个正常的接口请求
195
+ const response = await request.get('/api/notice/list', {
196
+ params: {
197
+ page: 1,
198
+ pageSize: 10
199
+ }
200
+ })
201
+
202
+ // 如果请求成功,显示结果
203
+ if (response && response.data) {
204
+ requestResult.value = JSON.stringify(response.data, null, 2)
205
+ showSuccessToast('请求成功,数据已更新')
206
+ } else {
207
+ // 模拟返回的数据
208
+ const mockData = [
209
+ { id: 1, title: '通知公告1', content: '这是通知公告1的内容' },
210
+ { id: 2, title: '通知公告2', content: '这是通知公告2的内容' },
211
+ { id: 3, title: '通知公告3', content: '这是通知公告3的内容' },
212
+ { id: 4, title: '通知公告4', content: '这是通知公告4的内容' },
213
+ { id: 5, title: '通知公告5', content: '这是通知公告5的内容' }
214
+ ]
215
+ requestResult.value = JSON.stringify(mockData, null, 2)
216
+ showSuccessToast('使用模拟数据(接口不存在)')
217
+ }
218
+
219
+ refreshStatistics()
220
+ } catch (error) {
221
+ // 错误会被错误监控自动捕获
222
+ requestResult.value = `错误: ${error.message || '未知错误'}`
223
+ showFailToast('请求失败:' + (error.message || '未知错误'))
224
+ refreshStatistics()
225
+ } finally {
226
+ loading.value = false
227
+ }
228
+ }
229
+
230
+ // 测试404错误
231
+ const test404Error = async () => {
232
+ loading.value = true
233
+ requestResult.value = ''
234
+
235
+ try {
236
+ await request.get('/api/not-found-endpoint-404')
237
+ } catch (error) {
238
+ requestResult.value = `404错误已捕获: ${error.message}`
239
+ showFailToast('404错误已捕获')
240
+ refreshStatistics()
241
+ } finally {
242
+ loading.value = false
243
+ }
244
+ }
245
+
246
+ // 测试500错误
247
+ const test500Error = async () => {
248
+ loading.value = true
249
+ requestResult.value = ''
250
+
251
+ try {
252
+ await request.get('/api/server-error-500')
253
+ } catch (error) {
254
+ requestResult.value = `500错误已捕获: ${error.message}`
255
+ showFailToast('500错误已捕获')
256
+ refreshStatistics()
257
+ } finally {
258
+ loading.value = false
259
+ }
260
+ }
261
+
262
+ // 测试网络错误
263
+ const testNetworkError = async () => {
264
+ loading.value = true
265
+ requestResult.value = ''
266
+
267
+ try {
268
+ // 临时修改baseURL来模拟网络错误
269
+ const originalBaseURL = request.defaults.baseURL
270
+ request.defaults.baseURL = 'https://non-existent-domain-12345-xyz.com'
271
+
272
+ await request.get('/api/test-network-error')
273
+
274
+ // 恢复baseURL
275
+ request.defaults.baseURL = originalBaseURL
276
+ } catch (error) {
277
+ requestResult.value = `网络错误已捕获: ${error.message}`
278
+ showFailToast('网络错误已捕获')
279
+ // 恢复baseURL
280
+ request.defaults.baseURL = import.meta.env.VITE_API_BASE_URL || ''
281
+ refreshStatistics()
282
+ } finally {
283
+ loading.value = false
284
+ }
285
+ }
286
+
287
+ // 测试超时错误
288
+ const testTimeoutError = async () => {
289
+ loading.value = true
290
+ requestResult.value = ''
291
+
292
+ try {
293
+ // 创建一个超时时间很短的请求
294
+ await request.get('/api/slow-endpoint', {
295
+ timeout: 100 // 100ms超时
296
+ })
297
+ } catch (error) {
298
+ requestResult.value = `超时错误已捕获: ${error.message}`
299
+ showFailToast('超时错误已捕获')
300
+ refreshStatistics()
301
+ } finally {
302
+ loading.value = false
303
+ }
304
+ }
305
+
306
+ // ============ 页面错误测试 ============
307
+
308
+ // 测试JavaScript错误
309
+ const testPageError = () => {
310
+ // 使用 setTimeout 确保错误不会被 try-catch 捕获
311
+ setTimeout(() => {
312
+ throw new Error('测试页面错误:这是一个模拟的前端JavaScript错误')
313
+ }, 0)
314
+ showToast('页面错误已触发,请查看控制台和日志')
315
+ setTimeout(() => {
316
+ refreshStatistics()
317
+ }, 100)
318
+ }
319
+
320
+ // 测试引用错误
321
+ const testReferenceError = () => {
322
+ setTimeout(() => {
323
+ // @ts-ignore
324
+ undefinedVariable.someProperty // 这会触发 ReferenceError
325
+ }, 0)
326
+ showToast('引用错误已触发,请查看控制台和日志')
327
+ setTimeout(() => {
328
+ refreshStatistics()
329
+ }, 100)
330
+ }
331
+
332
+ // 测试类型错误
333
+ const testTypeError = () => {
334
+ setTimeout(() => {
335
+ const obj = null
336
+ // @ts-ignore
337
+ obj.property // 这会触发 TypeError
338
+ }, 0)
339
+ showToast('类型错误已触发,请查看控制台和日志')
340
+ setTimeout(() => {
341
+ refreshStatistics()
342
+ }, 100)
343
+ }
344
+
345
+ // ============ Promise错误测试 ============
346
+
347
+ // 测试Promise未捕获错误
348
+ const testPromiseError = () => {
349
+ // 创建一个未处理的Promise错误
350
+ Promise.reject(new Error('测试Promise错误:这是一个未捕获的Promise错误'))
351
+ showToast('Promise错误已触发,请查看控制台和日志')
352
+ setTimeout(() => {
353
+ refreshStatistics()
354
+ }, 100)
355
+ }
356
+
357
+ // 测试Async函数错误
358
+ const testAsyncError = async () => {
359
+ // 创建一个异步函数,但不捕获错误
360
+ const asyncFunc = async () => {
361
+ throw new Error('测试Async函数错误:这是一个异步函数中的未捕获错误')
362
+ }
363
+
364
+ // 不等待,让它自己失败
365
+ asyncFunc().catch(() => {
366
+ // 即使这里捕获了,但如果在其他地方没有捕获,错误监控还是会捕获
367
+ })
368
+
369
+ // 触发一个真正未捕获的Promise错误
370
+ setTimeout(() => {
371
+ Promise.reject(new Error('Async函数中的未捕获Promise错误'))
372
+ }, 0)
373
+
374
+ showToast('Async错误已触发,请查看控制台和日志')
375
+ setTimeout(() => {
376
+ refreshStatistics()
377
+ }, 100)
378
+ }
379
+
380
+ // ============ Vue组件错误测试 ============
381
+
382
+ // 测试Vue组件渲染错误
383
+ const testVueError = () => {
384
+ shouldRenderError.value = true
385
+ showToast('Vue渲染错误已触发,请查看控制台和日志')
386
+ setTimeout(() => {
387
+ shouldRenderError.value = false
388
+ refreshStatistics()
389
+ }, 100)
390
+ }
391
+
392
+
393
+ // 初始化
394
+ onMounted(() => {
395
+ refreshStatistics()
396
+ })
397
+ </script>
398
+
399
+ <style lang="scss" scoped>
400
+ .test-error-page {
401
+ padding: 16px;
402
+ background-color: #f5f5f5;
403
+ min-height: 100vh;
404
+ }
405
+
406
+ .header {
407
+ display: flex;
408
+ justify-content: space-between;
409
+ align-items: center;
410
+ margin-bottom: 16px;
411
+
412
+ h2 {
413
+ margin: 0;
414
+ font-size: 20px;
415
+ font-weight: bold;
416
+ color: #333;
417
+ }
418
+ }
419
+
420
+ .stats-card {
421
+ display: grid;
422
+ grid-template-columns: repeat(4, 1fr);
423
+ gap: 12px;
424
+ margin-bottom: 20px;
425
+
426
+ .stat-item {
427
+ background: #fff;
428
+ border-radius: 8px;
429
+ padding: 16px;
430
+ text-align: center;
431
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
432
+
433
+ .stat-label {
434
+ font-size: 12px;
435
+ color: #666;
436
+ margin-bottom: 8px;
437
+ }
438
+
439
+ .stat-value {
440
+ font-size: 24px;
441
+ font-weight: bold;
442
+ color: #1989fa;
443
+ }
444
+ }
445
+ }
446
+
447
+ .test-section {
448
+ background: #fff;
449
+ border-radius: 8px;
450
+ padding: 16px;
451
+ margin-bottom: 16px;
452
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
453
+
454
+ .section-title {
455
+ font-size: 16px;
456
+ font-weight: bold;
457
+ color: #333;
458
+ margin-bottom: 12px;
459
+ padding-bottom: 8px;
460
+ border-bottom: 1px solid #f0f0f0;
461
+ }
462
+
463
+ .button-group {
464
+ display: flex;
465
+ flex-direction: column;
466
+ gap: 8px;
467
+ }
468
+
469
+ .result-box {
470
+ margin-top: 16px;
471
+ padding: 12px;
472
+ background-color: #f8f9fa;
473
+ border-radius: 4px;
474
+ border: 1px solid #e9ecef;
475
+
476
+ .result-title {
477
+ font-size: 14px;
478
+ font-weight: 500;
479
+ color: #333;
480
+ margin-bottom: 8px;
481
+ }
482
+
483
+ .result-content {
484
+ margin: 0;
485
+ font-size: 12px;
486
+ color: #666;
487
+ white-space: pre-wrap;
488
+ word-break: break-all;
489
+ max-height: 200px;
490
+ overflow-y: auto;
491
+ }
492
+ }
493
+ }
494
+
495
+ .refresh-section {
496
+ margin-top: 20px;
497
+ margin-bottom: 20px;
498
+ }
499
+ </style>
500
+