Merge pull request #4148 from albertgasset/MOBILE-4608

MOBILE 4608 core: Parse error message from HTML abd fix FileTransferMock
main
Dani Palou 2024-08-14 11:25:59 +02:00 committed by GitHub
commit 297cb57ff5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 43 additions and 42 deletions

View File

@ -12,7 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { CoreTextUtils } from '@services/utils/text';
import { CoreFile } from '@services/file';
/**
@ -117,25 +116,24 @@ export class FileTransferMock {
};
xhr.onerror = (): void => {
const error = new FileTransferErrorMock(-1, source, target, xhr.status, xhr.statusText, '');
const error = new FileTransferErrorMock(-1, source, target, xhr.status, '', '');
errorCallback(error);
};
xhr.onload = async (): Promise<void> => {
// Finished dowloading the file.
let response = xhr.response || xhr.responseText;
const status = Math.max(xhr.status === 1223 ? 204 : xhr.status, 0);
if (status < 200 || status >= 300) {
// Request failed. Try to get the error message.
response = await this.parseResponse(response);
const error = new FileTransferErrorMock(-1, source, target, xhr.status, response || xhr.statusText, '');
// Request failed. Try to get the respnse.
const body = xhr.response ? await this.blobToText(xhr.response) : '';
const error = new FileTransferErrorMock(-1, source, target, xhr.status, body, '');
return errorCallback(error);
}
if (!response) {
const error = new FileTransferErrorMock(-1, source, target, xhr.status, xhr.statusText, 'No response obtained');
if (!xhr.response) {
const error = new FileTransferErrorMock(-1, source, target, xhr.status, '', 'No response obtained');
return errorCallback(error);
}
@ -143,10 +141,16 @@ export class FileTransferMock {
const basePath = CoreFile.getBasePathInstant();
target = target.replace(basePath, ''); // Remove basePath from the target.
target = target.replace(/%20/g, ' '); // Replace all %20 with spaces.
CoreFile.writeFile(target, response)
.then(entry =>
successCallback({ entry: entry as unknown as globalThis.FileEntry, headers: response.headers }))
.catch(error => errorCallback(error));
try {
const entry = await CoreFile.writeFile(target, xhr.response) ;
successCallback({
entry: entry as unknown as globalThis.FileEntry,
headers: this.getHeadersAsObject(xhr),
});
} catch (error) {
errorCallback(error);
}
};
xhr.send();
@ -214,34 +218,6 @@ export class FileTransferMock {
return credentials && credentials[1];
}
/**
* Parse a response, converting it into text and the into an object if needed.
*
* @param response The response to parse.
* @returns Promise resolved with the parsed response.
*/
protected async parseResponse(response: Blob | ArrayBuffer | string | null): Promise<unknown> {
if (!response) {
return '';
}
let responseText = '';
if (response instanceof Blob) {
responseText = await this.blobToText(response);
} else if (response instanceof ArrayBuffer) {
// Convert the ArrayBuffer into text.
responseText = String.fromCharCode.apply(null, new Uint8Array(response));
} else {
responseText = response;
}
return CoreTextUtils.parseJSON(responseText, '');
}
/**
* Convert a Blob to text.
*
@ -336,7 +312,7 @@ export class FileTransferMock {
this.errorCallback = errorCallback;
xhr.onerror = (): void => {
const error = new FileTransferErrorMock(-1, fileUrl, url, xhr.status, xhr.statusText, '');
const error = new FileTransferErrorMock(-1, fileUrl, url, xhr.status, '', '');
errorCallback(error);
};

View File

@ -515,7 +515,32 @@ export class CoreTextUtilsProvider {
return undefined;
}
return error.message || error.error || error.content || error.body;
if (error.message || error.error || error.content) {
return error.message || error.error || error.content;
}
if (error.body) {
return this.getErrorMessageFromHTML(error.body);
}
return undefined;
}
/**
* Get the error message from an HTML error page.
*
* @param body HTML content.
* @returns Error message or empty string if not found.
*/
getErrorMessageFromHTML(body: string): string {
// THe parser does not throw errors and scripts are not executed.
const parser = new DOMParser();
const doc = parser.parseFromString(body, 'text/html');
// Errors are rendered using the "errorbox" and "errormessage" classes since Moodle 2.0.
const element = doc.body.querySelector<HTMLElement>('.errorbox .errormessage');
return element?.innerText.trim() ?? '';
}
/**