diff --git a/client/src/UDSClient.py b/client/src/UDSClient.py index 9ce27f10b..1db025065 100755 --- a/client/src/UDSClient.py +++ b/client/src/UDSClient.py @@ -45,6 +45,8 @@ import webbrowser from UDSWindow import Ui_MainWindow +class RetryException(Exception): + pass class UDSClient(QtGui.QMainWindow): @@ -77,6 +79,10 @@ class UDSClient(QtGui.QMainWindow): def processError(self, data): if 'error' in data: + # QtGui.QMessageBox.critical(self, 'Request error {}'.format(data.get('retryable', '0')), data['error'], QtGui.QMessageBox.Ok) + if data.get('retryable', '0') == '1': + raise RetryException(data['error']) + raise Exception(data['error']) # QtGui.QMessageBox.critical(self, 'Request error', rest.data['error'], QtGui.QMessageBox.Ok) # self.closeWindow() @@ -92,6 +98,13 @@ class UDSClient(QtGui.QMainWindow): def cancelPushed(self): self.close() + def _updateProgressBar(self, increment, maximum=100): + val = self.ui.progressBar.value() + val += increment + if val > maximum: + val = maximum + self.ui.progressBar.setValue(val) + @QtCore.pyqtSlot() def getVersion(self): self.req = RestRequest('', self, self.version) @@ -100,7 +113,7 @@ class UDSClient(QtGui.QMainWindow): @QtCore.pyqtSlot(dict) def version(self, data): try: - self.ui.progressBar.setValue(50) + self.ui.progressBar.setValue(20) self.processError(data) @@ -111,19 +124,29 @@ class UDSClient(QtGui.QMainWindow): webbrowser.open(data['result']['downloadUrl']) self.closeWindow() return + self.getTransportData() - self.req = RestRequest('/{}/{}'.format(self.ticket, self.scrambler), self, self.transportDataReceived, params={'hostname': tools.getHostName(), 'version': VERSION}) - self.req.get() + except RetryException as e: + self._updateProgressBar(5, 80) + self.ui.info.setText(six.text_type(e)) + QtCore.QTimer.singleShot(1000, self.getVersion) except Exception as e: self.showError(e) + @QtCore.pyqtSlot() + def getTransportData(self): + self.req = RestRequest('/{}/{}'.format(self.ticket, self.scrambler), self, self.transportDataReceived, params={'hostname': tools.getHostName(), 'version': VERSION}) + self.req.get() + + @QtCore.pyqtSlot(dict) def transportDataReceived(self, data): try: - self.ui.progressBar.setValue(80) self.processError(data) + self.ui.progressBar.setValue(80) + script = data['result'].decode('base64').decode('bz2') six.exec_(script, globals(), {'parent': self}) @@ -133,6 +156,12 @@ class UDSClient(QtGui.QMainWindow): QtCore.QTimer.singleShot(3000, self.endScript) + except RetryException as e: + self._updateProgressBar(5, 80) + self.ui.info.setText(six.text_type(e) + ', retrying access...') + # Retry operation in ten seconds + QtCore.QTimer.singleShot(10000, self.getTransportData) + except Exception as e: self.showError(e) diff --git a/server/src/uds/REST/methods/client.py b/server/src/uds/REST/methods/client.py index 289a38c7f..31185b595 100644 --- a/server/src/uds/REST/methods/client.py +++ b/server/src/uds/REST/methods/client.py @@ -63,7 +63,7 @@ class Client(Handler): authenticated = False # Client requests are not authenticated @staticmethod - def result(result=None, error=None, errorCode=0): + def result(result=None, error=None, errorCode=0, retryable=False): ''' Helper method to create a "result" set for actor response :param result: Result value to return (can be None, in which case it is converted to empty string '') @@ -79,6 +79,10 @@ class Client(Handler): error += ' (code {0:04X})'.format(errorCode) res['error'] = error + res['retryable'] = retryable and '1' or '0' + + logger.debug('Client Result: {}'.format(res)) + return res def test(self): @@ -140,7 +144,9 @@ class Client(Handler): return Client.result(result=transportScript.encode('bz2').encode('base64')) except ServiceNotReadyError as e: - return Client.result(error=errors.SERVICE_NOT_READY, errorCode=e.code) + # Refresh ticket and make this retrayable + TicketStore.revalidate(ticket, 20) # Retry will be in at most 5 seconds + return Client.result(error=errors.SERVICE_IN_PREPARATION, errorCode=e.code, retryable=True) except Exception as e: logger.exception("Exception") return Client.result(error=six.text_type(e)) diff --git a/server/src/uds/web/errors.py b/server/src/uds/web/errors.py index cd61240d0..7e8df8067 100644 --- a/server/src/uds/web/errors.py +++ b/server/src/uds/web/errors.py @@ -64,6 +64,7 @@ INVALID_REQUEST = 10 BROWSER_NOT_SUPPORTED = 11, SERVICE_IN_MAINTENANCE = 12 SERVICE_NOT_READY = 13 +SERVICE_IN_PREPARATION = 14 strings = [ @@ -80,7 +81,8 @@ strings = [ _('Invalid request received'), _('Your browser is not supported. Please, upgrade it to a modern HTML5 browser like Firefox or Chrome'), _('The requested service is in maintenance mode'), - _('The service is not ready.\nPlease, try again in a few moments.') + _('The service is not ready.\nPlease, try again in a few moments.'), + _('Preparing service') ]