Skip to content

Commit

Permalink
Merge pull request #4148 from albertgasset/MOBILE-4608
Browse files Browse the repository at this point in the history
MOBILE 4608 core: Parse error message from HTML abd fix FileTransferMock
  • Loading branch information
dpalou authored Aug 14, 2024
2 parents 071eee2 + 7866b31 commit 297cb57
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 42 deletions.
58 changes: 17 additions & 41 deletions src/core/features/emulator/services/file-transfer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

/**
Expand Down Expand Up @@ -117,36 +116,41 @@ 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);
}

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();
Expand Down Expand Up @@ -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.
*
Expand Down Expand Up @@ -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);
};

Expand Down
27 changes: 26 additions & 1 deletion src/core/services/utils/text.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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() ?? '';
}

/**
Expand Down

0 comments on commit 297cb57

Please sign in to comment.