Skip to content

Commit 9050830

Browse files
committed
Add fetch wrappers, ignore network errors in actions view
1 parent 049b9f3 commit 9050830

File tree

3 files changed

+57
-21
lines changed

3 files changed

+57
-21
lines changed

web_src/js/components/RepoActionView.vue

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ import {createApp} from 'vue';
55
import {toggleElem} from '../utils/dom.js';
66
import {getCurrentLocale} from '../utils.js';
77
import {renderAnsi} from '../render/ansi.js';
8-
9-
const {csrfToken} = window.config;
8+
import {POST, isNetworkError} from '../modules/fetch.js';
109
1110
const sfc = {
1211
name: 'RepoActionView',
@@ -145,11 +144,11 @@ const sfc = {
145144
},
146145
// cancel a run
147146
cancelRun() {
148-
this.fetchPost(`${this.run.link}/cancel`);
147+
POST(`${this.run.link}/cancel`);
149148
},
150149
// approve a run
151150
approveRun() {
152-
this.fetchPost(`${this.run.link}/approve`);
151+
POST(`${this.run.link}/approve`);
153152
},
154153
155154
createLogLine(line, startTime, stepIndex) {
@@ -203,10 +202,9 @@ const sfc = {
203202
// for example: make cursor=null means the first time to fetch logs, cursor=eof means no more logs, etc
204203
return {step: idx, cursor: it.cursor, expanded: it.expanded};
205204
});
206-
const resp = await this.fetchPost(
207-
`${this.actionsURL}/runs/${this.runIndex}/jobs/${this.jobIndex}`,
208-
JSON.stringify({logCursors}),
209-
);
205+
const resp = await POST(`${this.actionsURL}/runs/${this.runIndex}/jobs/${this.jobIndex}`, {
206+
json: {logCursors},
207+
});
210208
return await resp.json();
211209
},
212210
@@ -216,7 +214,7 @@ const sfc = {
216214
this.loading = true;
217215
218216
// refresh artifacts if upload-artifact step done
219-
const resp = await this.fetchPost(`${this.actionsURL}/runs/${this.runIndex}/artifacts`);
217+
const resp = await POST(`${this.actionsURL}/runs/${this.runIndex}/artifacts`);
220218
const artifacts = await resp.json();
221219
this.artifacts = artifacts['artifacts'] || [];
222220
@@ -244,23 +242,16 @@ const sfc = {
244242
clearInterval(this.intervalID);
245243
this.intervalID = null;
246244
}
245+
} catch (err) {
246+
// avoid error while unloading page with fetch in progress
247+
if (!isNetworkError(err.message)) {
248+
throw err;
249+
}
247250
} finally {
248251
this.loading = false;
249252
}
250253
},
251254
252-
253-
fetchPost(url, body) {
254-
return fetch(url, {
255-
method: 'POST',
256-
headers: {
257-
'Content-Type': 'application/json',
258-
'X-Csrf-Token': csrfToken,
259-
},
260-
body,
261-
});
262-
},
263-
264255
isDone(status) {
265256
return ['success', 'skipped', 'failure', 'cancelled'].includes(status);
266257
},

web_src/js/modules/fetch.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
const {csrfToken} = window.config;
2+
3+
function request(url, {headers, json, ...other} = {}) {
4+
return window.fetch(url, {
5+
headers: {
6+
'x-csrf-token': csrfToken,
7+
...(json && {'content-type': 'application/json'}),
8+
...headers,
9+
},
10+
...(json && {body: JSON.stringify(json)}),
11+
...other,
12+
});
13+
}
14+
15+
export const GET = (url, opts) => request(url, {method: 'GET', ...opts});
16+
export const POST = (url, opts) => request(url, {method: 'POST', ...opts});
17+
export const PATCH = (url, opts) => request(url, {method: 'PATCH', ...opts});
18+
export const PUT = (url, opts) => request(url, {method: 'PUT', ...opts});
19+
export const DELETE = (url, opts) => request(url, {method: 'DELETE', ...opts});
20+
21+
// network errors are currently only detectable by error message
22+
// based on https://github.com/sindresorhus/p-retry/blob/main/index.js
23+
const networkErrorMsgs = new Set([
24+
'Failed to fetch', // Chrome
25+
'NetworkError when attempting to fetch resource.', // Firefox
26+
'The Internet connection appears to be offline.', // Safari
27+
]);
28+
29+
export function isNetworkError(msg) {
30+
return networkErrorMsgs.has(msg);
31+
}

web_src/js/modules/fetch.test.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import {test, expect} from 'vitest';
2+
import {GET, POST, PATCH, PUT, DELETE, isNetworkError} from './fetch.js';
3+
4+
test('exports', () => {
5+
expect(GET).toBeTruthy();
6+
expect(POST).toBeTruthy();
7+
expect(PATCH).toBeTruthy();
8+
expect(PUT).toBeTruthy();
9+
expect(DELETE).toBeTruthy();
10+
});
11+
12+
test('isNetworkError', () => {
13+
expect(isNetworkError('Failed to fetch')).toEqual(true);
14+
});

0 commit comments

Comments
 (0)