Skip to content

Commit 4efd0b9

Browse files
committed
Allow specifying custom timeout and callback if POST fails
1 parent f0bd059 commit 4efd0b9

File tree

4 files changed

+47
-13
lines changed

4 files changed

+47
-13
lines changed

httpGUI/.editorconfig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[*.html]
2+
charset=utf-8
3+
insert_final_newline=true
4+
indent_style=tab
5+
indent_size=4
6+
7+
[*.js]
8+
charset=utf-8
9+
insert_final_newline=true
10+
indent_style=space
11+
indent_size=2

httpGUI/installer.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,7 @@ <h4>This patch is only for WINDOWS. It does not work on Mac or Linux</h4>
439439
<div v-if="pathAutoDetectionInProgress">
440440
<br>
441441
<h3><span>Please wait, path autodetection in progress</span><span class="loader"></span></h3>
442+
<h4>Detection may take up to {{ TIMEOUT_AUTO_DETECT_PATHS }} seconds.</h4>
442443
</div>
443444
<!-- Section allowing you to start install or choose game path to install -->
444445
<div v-bind:class="{ 'greyed-out-disabled': pathAutoDetectionInProgress }">

httpGUI/python-patcher-lib.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ window.onload = function onWindowLoaded() {
184184
partiallyUninstalledPaths: [],
185185
installErrorDescription: "",
186186
installDataLoaded: false,
187+
TIMEOUT_AUTO_DETECT_PATHS: 15,
187188
},
188189
methods: {
189190
doInstall(deleteVersionInformation) {
@@ -215,7 +216,8 @@ Continue install anyway?`)) {
215216
} else {
216217
app.selectedInstallPath = responseData.path;
217218
}
218-
});
219+
},
220+
Infinity);
219221
} else {
220222
app.selectedInstallPath = pathToInstall;
221223
}
@@ -338,6 +340,11 @@ Continue install anyway?`)) {
338340
this.selectedInstallPath = this.fullInstallConfigs[0].path;
339341
this.showPathSelectionButtons = false;
340342
}
343+
},
344+
app.TIMEOUT_AUTO_DETECT_PATHS * 1000,
345+
(errorMessage) => {
346+
app.pathAutoDetectionInProgress = false;
347+
alert(`Couldn't autodetect game path due to an error - please select game path manually.\n\nError: ${errorMessage}`);
341348
});
342349
} else {
343350
this.fullInstallConfigs = [];

httpGUI/python-patcher-rest-lib.js

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,20 +41,27 @@ function decodeJSONResponse(jsonString) {
4141
//
4242
// - onSuccessCallback (function(object)): A fn executed when a response is received
4343
// from the server. The fn should take the returned object as its only argument
44-
function doPost(requestType, requestData, onSuccessCallback) {
44+
function doPost(requestType, requestData, onSuccessCallback, timeout, onErrorCallback) {
4545
const http = new XMLHttpRequest();
4646
const url = 'installer_data'; // in python, is stored in 'self.path' on the handler class
4747

48+
function errorHandler(msg) {
49+
const message = `[${requestType}] POST Error - "${msg}" - You must have the install loader window/console open - it is required for the installation.`;
50+
console.log(message);
51+
POSTNotificationErrorCallback(message);
52+
if (typeof onErrorCallback !== 'undefined') {
53+
onErrorCallback(msg);
54+
}
55+
}
56+
4857
// in python, is retrieved by calling 'self.rfile.read(content_length)',
4958
// where content_length is in the header (see python code)
5059
http.open('POST', url, true);
5160

5261
// Send the proper header information along with the request
5362
http.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
5463

55-
// Call a function when the state changes.
56-
// TODO: add timeout here to notify user if server has crashed or stopped working
57-
http.onreadystatechange = function onReadyStateChange() {
64+
http.onload = () => {
5865
if (http.readyState === 4) {
5966
if (http.status === 200) {
6067
const [responseType, responseDataObject] = decodeJSONResponse(http.responseText);
@@ -67,18 +74,26 @@ function doPost(requestType, requestData, onSuccessCallback) {
6774
onSuccessCallback(responseDataObject);
6875
}
6976
} else {
70-
const errorCodeString = http.status === 0 ? '' : `[${http.status}]`;
71-
const message = `POST Error ${errorCodeString} on [${requestType}] - Please check the install loader window/console is open - it is required for the installation.`;
72-
console.log(message);
73-
POSTNotificationErrorCallback(message);
77+
errorHandler(`Unexpected HTTP Status [${http.status}]`);
7478
}
7579
}
7680
};
7781

78-
// Use a timeout of 8 seconds. After this POSTNotificationErrorCallback() will be called
79-
if (requestType !== 'showFileChooser') {
80-
http.timeout = 8000;
81-
}
82+
http.onabort = () => {
83+
errorHandler('POST Aborted');
84+
};
85+
86+
http.onerror = function () {
87+
errorHandler('POST Error');
88+
};
89+
90+
http.ontimeout = function (e) {
91+
errorHandler(`POST Timeout (${http.timeout / 1000}s)`);
92+
};
93+
94+
// Use a timeout of 8 seconds by default.
95+
// After this errorHandler()/POSTNotificationErrorCallback() will be called
96+
http.timeout = timeout !== 'undefined' ? timeout : 8000;
8297

8398
http.send(makeJSONRequest(requestType, requestData));
8499
}

0 commit comments

Comments
 (0)