Skip to content

Commit 6f410d7

Browse files
committed
Cancellable request improvements
1 parent 7e583e4 commit 6f410d7

File tree

3 files changed

+105
-41
lines changed

3 files changed

+105
-41
lines changed

src/components/JobPanel.vue

+12-40
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ import EventBusMixin from './EventBusMixin';
2626
import WorkPanelMixin from './WorkPanelMixin';
2727
import SyncButton from './SyncButton.vue';
2828
import Utils from '../utils.js';
29-
import { AbortController, Job } from '@openeo/js-client';
29+
import { Job } from '@openeo/js-client';
30+
import { cancellableRequest, showCancellableRequestError, CancellableRequestError } from './cancellableRequest';
3031
3132
const WorkPanelMixinInstance = WorkPanelMixin('jobs', 'batch job', 'batch jobs');
3233
@@ -39,8 +40,7 @@ export default {
3940
data() {
4041
return {
4142
watchers: {},
42-
jobUpdater: null,
43-
runId: 0
43+
jobUpdater: null
4444
};
4545
},
4646
mounted() {
@@ -145,48 +145,20 @@ export default {
145145
await this.queueJob(job);
146146
},
147147
async executeProcess() {
148-
let abortController = new AbortController();
149-
let snotifyConfig = {
150-
timeout: 0,
151-
type: 'async',
152-
buttons: [{
153-
text: 'Cancel',
154-
action: toast => {
155-
abortController.abort();
156-
this.$snotify.remove(toast.id, true);
157-
}
158-
}]
148+
const callback = async (abortController) => {
149+
const result = await this.connection.computeResult(this.process, null, null, abortController);
150+
this.broadcast('viewSyncResult', result);
159151
};
160-
let toast;
161152
try {
162-
this.runId++;
163-
let message = "A process is currently executed synchronously...";
164-
let title = `Run #${this.runId}`;
165-
let endlessPromise = () => new Promise(() => {}); // Pass a promise to snotify that never resolves as we manually close the toast
166-
toast = this.$snotify.async(message, title, endlessPromise, snotifyConfig);
167-
let result = await this.connection.computeResult(this.process, null, null, abortController);
168-
this.broadcast('viewSyncResult', result);
169-
} catch(error) {
170-
if (axios.isCancel(error)) {
171-
// Do nothing, we expected the cancellation
172-
}
173-
else if (typeof error.message === 'string' && Utils.isObject(error.response) && [400,500].includes(error.response.status)) {
174-
this.broadcast('viewLogs', [{
175-
id: error.id,
176-
code: error.code,
177-
level: 'error',
178-
message: error.message,
179-
links: error.links || []
180-
}]);
181-
Utils.error(this, "Synchronous processing failed. Please see the logs for details.", "Processing Error");
153+
await cancellableRequest(this, callback, 'Run');
154+
} catch (error) {
155+
if (error instanceof CancellableRequestError) {
156+
showCancellableRequestError(this, error);
182157
}
183158
else {
184-
Utils.exception(this, error, "Server Error");
185-
}
186-
} finally {
187-
if (toast) {
188-
this.$snotify.remove(toast.id, true);
159+
Utils.exception(this, error);
189160
}
161+
190162
}
191163
},
192164
jobCreated(job) {

src/components/cancellableRequest.js

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import { AbortController } from '@openeo/js-client';
2+
import Utils from '../utils';
3+
4+
export class CancellableRequestError extends Error {
5+
constructor(message, title = null, cause = null, close = true, isError = true) {
6+
super(message, {cause});
7+
this.title = title;
8+
this.close = close;
9+
this.isError = isError;
10+
}
11+
}
12+
13+
export function showCancellableRequestError(vm, error) {
14+
if (error instanceof CancellableRequestError) {
15+
if (error.isError) {
16+
Utils.error(vm, error.message, error.title);
17+
}
18+
else {
19+
Utils.ok(vm, error.message, error.title);
20+
}
21+
}
22+
}
23+
24+
let runIds = {};
25+
export async function cancellableRequest(vm, callback, entity) {
26+
if (!runIds[entity]) {
27+
runIds[entity] = 1;
28+
}
29+
else {
30+
runIds[entity]++;
31+
}
32+
33+
const abortController = new AbortController();
34+
const snotifyConfig = Object.assign({}, vm.$config.snotifyDefaults, {
35+
timeout: 0,
36+
type: 'async',
37+
buttons: [{
38+
text: 'Cancel',
39+
action: () => {
40+
abortController.abort();
41+
}
42+
}]
43+
});
44+
45+
let toast;
46+
const toastTitle = `${entity} #${runIds[entity]}`;
47+
try {
48+
const message = `Processing in progress, please wait...`;
49+
// Pass a promise to snotify that never resolves as we manually close the toast
50+
const endlessPromise = () => new Promise(() => {});
51+
toast = vm.$snotify.async(message, toastTitle, endlessPromise, snotifyConfig);
52+
53+
await callback(abortController);
54+
} catch(error) {
55+
if (axios.isCancel(error)) {
56+
throw new CancellableRequestError(`Cancelled successfully`, toastTitle, error, false, false);
57+
}
58+
else if (typeof error.message === 'string' && Utils.isObject(error.response) && [400,500].includes(error.response.status)) {
59+
vm.broadcast('viewLogs', [{
60+
id: error.id,
61+
code: error.code,
62+
level: 'error',
63+
message: error.message,
64+
links: error.links || []
65+
}]);
66+
Utils.error(vm, `${entity} failed. Please see the logs for details.`, toastTitle);
67+
}
68+
else {
69+
throw new CancellableRequestError(error.message, toastTitle, error, false);
70+
}
71+
} finally {
72+
if (toast) {
73+
vm.$snotify.remove(toast.id, true);
74+
}
75+
}
76+
}

src/components/modals/WizardModal.vue

+17-1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ import WizardStep from '../wizards/components/WizardStep.vue';
6060
import Utils from '../../utils';
6161
import Config from '../../../config';
6262
import EventBusMixin from '../EventBusMixin';
63+
import { CancellableRequestError } from '../cancellableRequest';
6364
6465
const wizards = Config.supportedWizards || [];
6566
let components = {
@@ -248,7 +249,22 @@ export default {
248249
else if (this.isLastStep) {
249250
this.$refs.component.finish()
250251
.then(this.close)
251-
.catch(error => Utils.exception(this, error));
252+
.catch(error => {
253+
if (error instanceof CancellableRequestError) {
254+
if (error.isError) {
255+
Utils.exception(this, error, error.title);
256+
}
257+
else {
258+
Utils.ok(this, error.message, error.title);
259+
}
260+
if (error.close) {
261+
this.close();
262+
}
263+
}
264+
else {
265+
Utils.exception(this, error);
266+
}
267+
});
252268
}
253269
}
254270
this.beforeTabChange(this.activeTabIndex, cb);

0 commit comments

Comments
 (0)