Skip to content

Commit

Permalink
Add fetch wrappers, ignore network errors in actions view
Browse files Browse the repository at this point in the history
  • Loading branch information
silverwind committed Sep 9, 2023
1 parent 049b9f3 commit 9050830
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 21 deletions.
33 changes: 12 additions & 21 deletions web_src/js/components/RepoActionView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ import {createApp} from 'vue';
import {toggleElem} from '../utils/dom.js';
import {getCurrentLocale} from '../utils.js';
import {renderAnsi} from '../render/ansi.js';
const {csrfToken} = window.config;
import {POST, isNetworkError} from '../modules/fetch.js';
const sfc = {
name: 'RepoActionView',
Expand Down Expand Up @@ -145,11 +144,11 @@ const sfc = {
},
// cancel a run
cancelRun() {
this.fetchPost(`${this.run.link}/cancel`);
POST(`${this.run.link}/cancel`);
},
// approve a run
approveRun() {
this.fetchPost(`${this.run.link}/approve`);
POST(`${this.run.link}/approve`);
},
createLogLine(line, startTime, stepIndex) {
Expand Down Expand Up @@ -203,10 +202,9 @@ const sfc = {
// for example: make cursor=null means the first time to fetch logs, cursor=eof means no more logs, etc
return {step: idx, cursor: it.cursor, expanded: it.expanded};
});
const resp = await this.fetchPost(
`${this.actionsURL}/runs/${this.runIndex}/jobs/${this.jobIndex}`,
JSON.stringify({logCursors}),
);
const resp = await POST(`${this.actionsURL}/runs/${this.runIndex}/jobs/${this.jobIndex}`, {
json: {logCursors},
});
return await resp.json();
},
Expand All @@ -216,7 +214,7 @@ const sfc = {
this.loading = true;
// refresh artifacts if upload-artifact step done
const resp = await this.fetchPost(`${this.actionsURL}/runs/${this.runIndex}/artifacts`);
const resp = await POST(`${this.actionsURL}/runs/${this.runIndex}/artifacts`);
const artifacts = await resp.json();
this.artifacts = artifacts['artifacts'] || [];
Expand Down Expand Up @@ -244,23 +242,16 @@ const sfc = {
clearInterval(this.intervalID);
this.intervalID = null;
}
} catch (err) {
// avoid error while unloading page with fetch in progress
if (!isNetworkError(err.message)) {
throw err;
}
} finally {
this.loading = false;
}
},
fetchPost(url, body) {
return fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Csrf-Token': csrfToken,
},
body,
});
},
isDone(status) {
return ['success', 'skipped', 'failure', 'cancelled'].includes(status);
},
Expand Down
31 changes: 31 additions & 0 deletions web_src/js/modules/fetch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const {csrfToken} = window.config;

function request(url, {headers, json, ...other} = {}) {
return window.fetch(url, {
headers: {
'x-csrf-token': csrfToken,
...(json && {'content-type': 'application/json'}),
...headers,
},
...(json && {body: JSON.stringify(json)}),
...other,
});
}

export const GET = (url, opts) => request(url, {method: 'GET', ...opts});
export const POST = (url, opts) => request(url, {method: 'POST', ...opts});
export const PATCH = (url, opts) => request(url, {method: 'PATCH', ...opts});
export const PUT = (url, opts) => request(url, {method: 'PUT', ...opts});
export const DELETE = (url, opts) => request(url, {method: 'DELETE', ...opts});

// network errors are currently only detectable by error message
// based on https://github.com/sindresorhus/p-retry/blob/main/index.js
const networkErrorMsgs = new Set([
'Failed to fetch', // Chrome
'NetworkError when attempting to fetch resource.', // Firefox
'The Internet connection appears to be offline.', // Safari
]);

export function isNetworkError(msg) {
return networkErrorMsgs.has(msg);
}
14 changes: 14 additions & 0 deletions web_src/js/modules/fetch.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import {test, expect} from 'vitest';
import {GET, POST, PATCH, PUT, DELETE, isNetworkError} from './fetch.js';

test('exports', () => {
expect(GET).toBeTruthy();
expect(POST).toBeTruthy();
expect(PATCH).toBeTruthy();
expect(PUT).toBeTruthy();
expect(DELETE).toBeTruthy();
});

test('isNetworkError', () => {
expect(isNetworkError('Failed to fetch')).toEqual(true);
});

0 comments on commit 9050830

Please sign in to comment.