|
1 | 1 | import omit from 'lodash/omit';
|
2 |
| -import axios from 'axios'; |
| 2 | +import axios, { isCancel } from 'axios'; |
3 | 3 | import qs from 'qs';
|
4 | 4 | import * as Sentry from '@sentry/vue';
|
5 | 5 |
|
@@ -38,26 +38,49 @@ window.addEventListener('offline', () => {
|
38 | 38 | lastOffline = Date.now();
|
39 | 39 | });
|
40 | 40 |
|
| 41 | +const pendingRequests = new Set(); |
| 42 | + |
| 43 | +const abortController = new AbortController(); |
| 44 | + |
| 45 | +window.addEventListener('navigate', () => { |
| 46 | + // Create a fresh AbortController to ensure proper cancellation of requests |
| 47 | + // for each navigation and prevent interference from previous aborts. |
| 48 | + const newAbortController = new AbortController(); |
| 49 | + abortController.signal = newAbortController.signal; |
| 50 | + |
| 51 | + abortController.abort(); |
| 52 | +}); |
| 53 | + |
| 54 | +window.addEventListener('beforeunload', () => { |
| 55 | + abortController.abort(); |
| 56 | +}); |
| 57 | + |
| 58 | +client.interceptors.request.use(config => { |
| 59 | + config.signal = abortController.signal; |
| 60 | + pendingRequests.add(config); |
| 61 | + return config; |
| 62 | +}); |
| 63 | + |
41 | 64 | client.interceptors.response.use(
|
42 |
| - response => response, |
| 65 | + response => { |
| 66 | + pendingRequests.delete(response.config); |
| 67 | + return response; |
| 68 | + }, |
43 | 69 | error => {
|
44 |
| - const url = error.config.url; |
45 |
| - let message = error.message; |
46 |
| - let status = 0; |
47 |
| - if (error.response) { |
48 |
| - status = error.response.status; |
49 |
| - message = error.response.statusText; |
50 |
| - // Don't send a Sentry report for permissions errors |
51 |
| - // Many 404s are in fact also unauthorized requests so |
52 |
| - // we should silence those on the front end and try |
53 |
| - // to catch legitimate request issues in the backend. |
54 |
| - // |
55 |
| - // Allow 412 too as that's specific to out of storage checks |
56 |
| - if (status === 403 || status === 404 || status === 405 || status === 412) { |
57 |
| - return Promise.reject(error); |
58 |
| - } |
| 70 | + if (error.config) { |
| 71 | + pendingRequests.delete(error.config); |
59 | 72 | }
|
60 | 73 |
|
| 74 | + if ( |
| 75 | + isCancel(error) || |
| 76 | + (error.response && [302, 403, 404, 405, 412].includes(error.response.status)) |
| 77 | + ) { |
| 78 | + return Promise.reject(error); |
| 79 | + } |
| 80 | + const url = error.config?.url || 'unknown'; |
| 81 | + let message = error.message; |
| 82 | + const status = error.response?.status || 0; |
| 83 | + |
61 | 84 | message = message ? `${message}: [${status}] ${url}` : `Network Error: [${status}] ${url}`;
|
62 | 85 |
|
63 | 86 | if (process.env.NODE_ENV !== 'production') {
|
|
0 commit comments