Merge pull request #4148 from albertgasset/MOBILE-4608
MOBILE 4608 core: Parse error message from HTML abd fix FileTransferMockmain
commit
297cb57ff5
|
@ -12,7 +12,6 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { CoreTextUtils } from '@services/utils/text';
|
|
||||||
import { CoreFile } from '@services/file';
|
import { CoreFile } from '@services/file';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -117,25 +116,24 @@ export class FileTransferMock {
|
||||||
};
|
};
|
||||||
|
|
||||||
xhr.onerror = (): void => {
|
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);
|
errorCallback(error);
|
||||||
};
|
};
|
||||||
|
|
||||||
xhr.onload = async (): Promise<void> => {
|
xhr.onload = async (): Promise<void> => {
|
||||||
// Finished dowloading the file.
|
// Finished dowloading the file.
|
||||||
let response = xhr.response || xhr.responseText;
|
|
||||||
|
|
||||||
const status = Math.max(xhr.status === 1223 ? 204 : xhr.status, 0);
|
const status = Math.max(xhr.status === 1223 ? 204 : xhr.status, 0);
|
||||||
if (status < 200 || status >= 300) {
|
if (status < 200 || status >= 300) {
|
||||||
// Request failed. Try to get the error message.
|
// Request failed. Try to get the respnse.
|
||||||
response = await this.parseResponse(response);
|
const body = xhr.response ? await this.blobToText(xhr.response) : '';
|
||||||
const error = new FileTransferErrorMock(-1, source, target, xhr.status, response || xhr.statusText, '');
|
const error = new FileTransferErrorMock(-1, source, target, xhr.status, body, '');
|
||||||
|
|
||||||
return errorCallback(error);
|
return errorCallback(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!response) {
|
if (!xhr.response) {
|
||||||
const error = new FileTransferErrorMock(-1, source, target, xhr.status, xhr.statusText, 'No response obtained');
|
const error = new FileTransferErrorMock(-1, source, target, xhr.status, '', 'No response obtained');
|
||||||
|
|
||||||
return errorCallback(error);
|
return errorCallback(error);
|
||||||
}
|
}
|
||||||
|
@ -143,10 +141,16 @@ export class FileTransferMock {
|
||||||
const basePath = CoreFile.getBasePathInstant();
|
const basePath = CoreFile.getBasePathInstant();
|
||||||
target = target.replace(basePath, ''); // Remove basePath from the target.
|
target = target.replace(basePath, ''); // Remove basePath from the target.
|
||||||
target = target.replace(/%20/g, ' '); // Replace all %20 with spaces.
|
target = target.replace(/%20/g, ' '); // Replace all %20 with spaces.
|
||||||
CoreFile.writeFile(target, response)
|
|
||||||
.then(entry =>
|
try {
|
||||||
successCallback({ entry: entry as unknown as globalThis.FileEntry, headers: response.headers }))
|
const entry = await CoreFile.writeFile(target, xhr.response) ;
|
||||||
.catch(error => errorCallback(error));
|
successCallback({
|
||||||
|
entry: entry as unknown as globalThis.FileEntry,
|
||||||
|
headers: this.getHeadersAsObject(xhr),
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
errorCallback(error);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
xhr.send();
|
xhr.send();
|
||||||
|
@ -214,34 +218,6 @@ export class FileTransferMock {
|
||||||
return credentials && credentials[1];
|
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.
|
* Convert a Blob to text.
|
||||||
*
|
*
|
||||||
|
@ -336,7 +312,7 @@ export class FileTransferMock {
|
||||||
this.errorCallback = errorCallback;
|
this.errorCallback = errorCallback;
|
||||||
|
|
||||||
xhr.onerror = (): void => {
|
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);
|
errorCallback(error);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -515,7 +515,32 @@ export class CoreTextUtilsProvider {
|
||||||
return undefined;
|
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() ?? '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue