Remove reliance on statusText for error messages. (#5056)

HTTP/2 does not support statusText, and proxies might replace it. Use the response body instead.

Closes #4729
This commit is contained in:
Jan
2023-12-12 23:17:12 +01:00
committed by GitHub
parent b08b59228c
commit 6c8ecb7b8e
10 changed files with 43 additions and 45 deletions
@@ -92,6 +92,10 @@ namespace Duplicati.Server.WebServer.RESTMethods
{
Response.Status = code;
Response.Reason = reason ?? "Error";
if(item == null && reason != null)
{
item = new { Error = reason };
}
BodyWriter.WriteJsonObject(item);
}
@@ -170,9 +170,7 @@ backupApp.controller('CommandlineController', function($scope, $routeParams, $lo
$scope.Command = 'backup';
},
function(resp) {
var message = resp.statusText;
if (resp.data != null && resp.data.Message != null)
message = resp.data.Message;
var message = AppService.responseErrorMessage(resp);
DialogService.dialog(gettextCatalog.getString('Error'), gettextCatalog.getString('Failed to connect: {{message}}', { message: message }));
}
@@ -35,10 +35,7 @@ backupApp.controller("ExportController", function($scope, $routeParams, AppServi
},
function(resp) {
$scope.Connecting = false;
var message = resp.statusText;
if (resp.data != null && resp.data.Message != null) {
message = resp.data.Message;
}
var message = AppService.responseErrorMessage(resp);
DialogService.dialog(gettextCatalog.getString("Error"), gettextCatalog.getString("Failed to connect: {{message}}", { message: message }));
}
@@ -83,9 +83,7 @@ backupApp.controller('RestoreController', function ($rootScope, $scope, $routePa
},
function(resp) {
var message = resp.statusText;
if (resp.data != null && resp.data.Message != null)
message = resp.data.Message;
var message = AppService.responseErrorMessage(resp);
$scope.connecting = false;
$scope.ConnectionProgress = '';
@@ -112,9 +110,7 @@ backupApp.controller('RestoreController', function ($rootScope, $scope, $routePa
$scope.connecting = false;
$scope.ConnectionProgress = '';
var message = resp.statusText;
if (resp.data != null && resp.data.Message != null)
message = resp.data.Message;
var message = AppService.responseErrorMessage(resp);
DialogService.dialog(gettextCatalog.getString('Error'), gettextCatalog.getString('Failed to fetch path information: {{message}}', { message: message }));
};
@@ -291,9 +287,7 @@ backupApp.controller('RestoreController', function ($rootScope, $scope, $routePa
},
function(resp) {
$scope.Searching = false;
var message = resp.statusText;
if (resp.data != null && resp.data.Message != null)
message = resp.data.Message;
var message = AppService.responseErrorMessage(resp);
$scope.connecting = false;
$scope.ConnectionProgress = '';
@@ -330,9 +324,7 @@ backupApp.controller('RestoreController', function ($rootScope, $scope, $routePa
$scope.restore_step = 2;
function handleError(resp) {
var message = resp.statusText;
if (resp.data != null && resp.data.Message != null)
message = resp.data.Message;
var message = AppService.responseErrorMessage(resp);
$scope.restore_step = 1;
$scope.connecting = false;
@@ -433,9 +425,7 @@ backupApp.controller('RestoreController', function ($rootScope, $scope, $routePa
DialogService.dialog(gettextCatalog.getString('Error'), gettextCatalog.getString('Failed to restore files: {{message}}', { message: resp.data.ErrorMessage }));
}
}, function(resp) {
var message = resp.statusText;
if (resp.data != null && resp.data.Message != null)
message = resp.data.Message;
var message = AppService.responseErrorMessage(resp);
$scope.restore_step = 1;
$scope.connecting = false;
@@ -65,9 +65,7 @@ backupApp.controller('RestoreDirectController', function ($rootScope, $scope, $l
$scope.BackupID = resp.data.ID;
$scope.fetchBackupTimes();
}, function(resp) {
var message = resp.statusText;
if (resp.data != null && resp.data.Message != null)
message = resp.data.Message;
var message = AppService.responseErrorMessage(resp);
$scope.connecting = false;
$scope.ConnectionProgress = '';
@@ -98,9 +96,7 @@ backupApp.controller('RestoreDirectController', function ($rootScope, $scope, $l
},
function(resp) {
var message = resp.statusText;
if (resp.data != null && resp.data.Message != null)
message = resp.data.Message;
var message = AppService.responseErrorMessage(resp);
if (message == 'encrypted-storage')
message = gettextCatalog.getString('The target folder contains encrypted files, please supply the passphrase');
@@ -118,7 +118,7 @@ backupApp.directive('backupEditUri', function(gettextCatalog) {
if (dlg != null)
dlg.dismiss();
var message = data.statusText;
var message = AppService.responseErrorMessage(data);
if (!hasTriedCreate && message == 'missing-folder')
{
@@ -163,9 +163,7 @@ backupApp.directive('backupEditUri', function(gettextCatalog) {
}, function(resp) {
scope.Testing = false;
message = resp.statusText;
if (data.data != null && data.data.Message != null)
message = data.data.Message;
message = AppService.responseErrorMessage(resp);
DialogService.dialog(gettextCatalog.getString('Error'), gettextCatalog.getString('Failed to import: ') + message);
@@ -123,4 +123,24 @@ backupApp.service('AppService', function($http, $cookies, $q, $cookies, DialogSe
return installResponseHook($http.get(this.proxy_url == null ? rurl : this.proxy_url, setupConfig('GET', {}, null, rurl)));
};
this.responseErrorMessage = function (resp) {
if (resp == null) {
return '';
}
var message = resp.statusText;
if (resp.data != null) {
// Different ways to communicate error message (this should be refactored in the server at some point)
if (resp.data.Message != null) {
message = resp.data.Message;
} else if (resp.data.Error != null) {
message = resp.data.Error;
}else if (resp.data.message != null) {
message = resp.data.message;
} else if (resp.data.reason != null) {
message = resp.data.reason;
}
}
return message;
};
});
@@ -360,21 +360,17 @@ backupApp.service('AppUtils', function($rootScope, $timeout, $cookies, DialogSer
this.connectionError = function(txt, msg) {
if (typeof(txt) == typeof('')) {
if (msg == null)
return function(msg) {
if (msg && msg.data && msg.data.Message)
DialogService.dialog(gettextCatalog.getString('Error'), txt + msg.data.Message);
else
DialogService.dialog(gettextCatalog.getString('Error'), txt + msg.statusText);
return function (msg) {
var msgText = AppService.responseErrorMessage(msg);
DialogService.dialog(gettextCatalog.getString('Error'), txt + msgText);
};
} else {
msg = txt;
txt = '';
}
if (msg && msg.data && msg.data.Message)
DialogService.dialog(gettextCatalog.getString('Error'), txt + msg.data.Message);
else
DialogService.dialog(gettextCatalog.getString('Error'), txt + msg.statusText);
var msgText = AppService.responseErrorMessage(msg);
DialogService.dialog(gettextCatalog.getString('Error'), txt + msgText);
};
this.generatePassphrase = function() {
@@ -23,9 +23,7 @@ backupApp.service('LogService', function(AppService, DialogService, gettextCatal
// $scope.Backup = BackupList.lookup[$scope.BackupID];
resolve({ current: current, complete: resp.data.length < pageSize });
}, function(resp) {
var message = resp.statusText;
if (resp.data != null && resp.data.Message != null)
message = resp.data.Message;
var message = AppService.responseErrorMessage(resp);
loadingData = false;
DialogService.dialog('Error', gettextCatalog.getString('Failed to connect: {{message}}', { message: message }));
@@ -267,7 +267,8 @@ backupApp.service('ServerStatus', function($rootScope, $timeout, AppService, App
var oldxsfrstate = state.xsfrerror;
state.failedConnectionAttempts++;
state.xsfrerror = response.statusText.toLowerCase().indexOf('xsrf') >= 0;
var errorMessage = AppService.responseErrorMessage(response);
state.xsfrerror = errorMessage.toLowerCase().indexOf('xsrf') >= 0;
// First failure, we ignore
if (state.connectionState == 'connected' && state.failedConnectionAttempts == 1) {