diff --git a/l10n/bundle.l10n.json b/l10n/bundle.l10n.json index df27d0174..c99dac311 100644 --- a/l10n/bundle.l10n.json +++ b/l10n/bundle.l10n.json @@ -16,9 +16,10 @@ "There was a permissions problem with the server": "There was a permissions problem with the server", "There’s a problem on the back end": "There’s a problem on the back end", "Try again": "Try again", - "We encountered an error preparing the file for edit.": "We encountered an error preparing the file for edit.", + "We encountered an error preparing the files for edit.": "We encountered an error preparing the files for edit.", + "Response data is empty": "Response data is empty", "Failed to fetch some files.": "Failed to fetch some files.", - "Failed to get file ready for edit.": "Failed to get file ready for edit.", + "Failed to get file ready for edit: {0}": "Failed to get file ready for edit: {0}", "Saving your file ...": "Saving your file ...", "Enter Organization ID": "Enter Organization ID", "Power Pages Copilot is now connected to the environment: {0} : {1}/{0} represents the environment name": { diff --git a/loc/translations-export/vscode-powerplatform.xlf b/loc/translations-export/vscode-powerplatform.xlf index 30afc1af9..8d60676bc 100644 --- a/loc/translations-export/vscode-powerplatform.xlf +++ b/loc/translations-export/vscode-powerplatform.xlf @@ -111,8 +111,8 @@ The {3} represents Solution's Type (Managed or Unmanaged), but that test is loca Failed to fetch some files. - - Failed to get file ready for edit. + + Failed to get file ready for edit: {0} Fetching your file ... @@ -234,6 +234,9 @@ The {3} represents Dataverse Environment's Organization ID (GUID) Resource: {0} The {0} represents profile's resource/environment URL + + Response data is empty + Saving your file ... @@ -284,8 +287,8 @@ The {3} represents Dataverse Environment's Organization ID (GUID) User: {0} The {0} represents auth profile's user name (email address)) - - We encountered an error preparing the file for edit. + + We encountered an error preparing the files for edit. Web files diff --git a/src/web/client/dal/remoteFetchProvider.ts b/src/web/client/dal/remoteFetchProvider.ts index 5e594aafe..1ae78b2d5 100644 --- a/src/web/client/dal/remoteFetchProvider.ts +++ b/src/web/client/dal/remoteFetchProvider.ts @@ -61,7 +61,7 @@ export async function fetchDataFromDataverseAndUpdateVFS( showErrorDialog( vscode.l10n.t("There was a problem opening the workspace"), vscode.l10n.t( - "We encountered an error preparing the file for edit." + "We encountered an error preparing the files for edit." ) ); WebExtensionContext.telemetry.sendErrorTelemetry(telemetryEventNames.WEB_EXTENSION_FAILED_TO_PREPARE_WORKSPACE, fetchDataFromDataverseAndUpdateVFS.name, errorMsg, error as Error); @@ -116,10 +116,7 @@ async function fetchFromDataverseAndCreateFiles( } if (result[Constants.ODATA_COUNT] !== 0 && data.length === 0) { - vscode.window.showErrorMessage( - "microsoft-powerapps-portals.webExtension.fetch.nocontent.error", - "Response data is empty" - ); + console.error(vscode.l10n.t("Response data is empty")); throw new Error(ERRORS.EMPTY_RESPONSE); } @@ -147,9 +144,7 @@ async function fetchFromDataverseAndCreateFiles( } catch (error) { makeRequestCall = false; const errorMsg = (error as Error)?.message; - vscode.window.showErrorMessage( - vscode.l10n.t("Failed to fetch some files.") - ); + console.error(vscode.l10n.t("Failed to fetch some files.")); if ((error as Response)?.status > 0) { WebExtensionContext.telemetry.sendAPIFailureTelemetry( requestUrl, @@ -194,6 +189,7 @@ async function createContentFiles( filePathInPortalFS?: string, defaultFileInfo?: IFileInfo, ) { + let fileName = ""; try { const entityDetails = getEntity(entityName); const attributes = entityDetails?.get(schemaEntityKey.ATTRIBUTES); @@ -227,7 +223,7 @@ async function createContentFiles( throw new Error(ERRORS.FILE_ID_EMPTY); } - const fileName = fetchedFileName + fileName = fetchedFileName ? result[fetchedFileName] : Constants.EMPTY_FILE_NAME; @@ -291,9 +287,7 @@ async function createContentFiles( } catch (error) { const errorMsg = (error as Error)?.message; - vscode.window.showErrorMessage( - vscode.l10n.t("Failed to get file ready for edit.") - ); + console.error(vscode.l10n.t("Failed to get file ready for edit: {0}", fileName)); WebExtensionContext.telemetry.sendErrorTelemetry( telemetryEventNames.WEB_EXTENSION_CONTENT_FILE_CREATION_FAILED, createContentFiles.name, @@ -361,7 +355,7 @@ async function processDataAndCreateFile( let rootWebPageId = undefined; if (rootWebPageIdAttribute) { - const rootWebPageIdPath : IAttributePath = getAttributePath(rootWebPageIdAttribute); + const rootWebPageIdPath: IAttributePath = getAttributePath(rootWebPageIdAttribute); rootWebPageId = getAttributeContent(result, rootWebPageIdPath, entityName, entityId); } diff --git a/src/web/client/test/integration/remoteFetchProvider.test.ts b/src/web/client/test/integration/remoteFetchProvider.test.ts index d28b30b8e..d788bea14 100644 --- a/src/web/client/test/integration/remoteFetchProvider.test.ts +++ b/src/web/client/test/integration/remoteFetchProvider.test.ts @@ -404,7 +404,7 @@ describe("remoteFetchProvider", () => { assert.callCount(sendAPISuccessTelemetry, 4); }); - it("fetchDataFromDataverseAndUpdateVFS_whenResponseSuccessButDataIsNull_shouldCallShowErrorMessage", async () => { + it("fetchDataFromDataverseAndUpdateVFS_whenResponseSuccessButDataIsNull_shouldSendErrorTelemetry", async () => { //Act const entityName = "webpages"; const entityId = "aa563be7-9a38-4a89-9216-47f9fc6a3f14"; @@ -490,7 +490,7 @@ describe("remoteFetchProvider", () => { assert.calledOnce(_mockFetch); }); - it("fetchDataFromDataverseAndUpdateVFS_whenResponseNotSuccess_shouldCallShowErrorMessage", async () => { + it("fetchDataFromDataverseAndUpdateVFS_whenResponseNotSuccess_shouldCallSendErrorTelemetry", async () => { //Act const entityName = "webpages"; const entityId = "aa563be7-9a38-4a89-9216-47f9fc6a3f14"; @@ -504,12 +504,15 @@ describe("remoteFetchProvider", () => { [schemaKey.SCHEMA_VERSION, "portalschemav2"], ]); - const showErrorMessage = stub(vscode.window, "showErrorMessage"); WebExtensionContext.setWebExtensionContext( entityName, entityId, queryParamsMap ); + const sendErrorTelemetry = stub( + WebExtensionContext.telemetry, + "sendErrorTelemetry" + ); const languageIdCodeMap = new Map([["1033", "en-US"]]); stub(schemaHelperUtil, "getLcidCodeMap").returns(languageIdCodeMap); @@ -553,9 +556,9 @@ describe("remoteFetchProvider", () => { json: () => { return new Promise((resolve) => { return resolve({ - "@odata.count": 1, - "@Microsoft.Dynamics.CRM.totalrecordcount": 1, - "value": null, + "@odata.count": 0, + "@Microsoft.Dynamics.CRM.totalrecordcount": 0, + "value": [], }); }); }, @@ -566,13 +569,26 @@ describe("remoteFetchProvider", () => { await fetchDataFromDataverseAndUpdateVFS(portalFs); //Assert + const sendErrorTelemetryCalls = sendErrorTelemetry.getCalls(); + + assert.callCount(sendErrorTelemetry, 5); + assert.calledWithMatch(sendErrorTelemetryCalls[0], telemetryEventNames.WEB_EXTENSION_POPULATE_WEBSITE_ID_TO_LANGUAGE_SYSTEM_ERROR, + "populateWebsiteIdToLanguageMap", + "Only absolute URLs are supported"); + assert.calledWithMatch(sendErrorTelemetryCalls[1], telemetryEventNames.WEB_EXTENSION_POPULATE_WEBSITE_LANGUAGE_ID_TO_PORTALLANGUAGE_SYSTEM_ERROR, + "populateWebsiteLanguageIdToPortalLanguageMap", + "Only absolute URLs are supported"); + assert.calledWithMatch(sendErrorTelemetryCalls[2], telemetryEventNames.WEB_EXTENSION_POPULATE_LANGUAGE_ID_TO_CODE_SYSTEM_ERROR, + "populateLanguageIdToCode", + "Only absolute URLs are supported"); + assert.calledWithMatch(sendErrorTelemetryCalls[3], telemetryEventNames.WEB_EXTENSION_POPULATE_SHARED_WORKSPACE_SYSTEM_ERROR, + "populateSharedWorkspace", + "Web extension populate shared workspace system error"); + assert.calledWithMatch(sendErrorTelemetryCalls[4], + telemetryEventNames.WEB_EXTENSION_FETCH_DATAVERSE_AND_CREATE_FILES_SYSTEM_ERROR, + "fetchFromDataverseAndCreateFiles", + `{"ok":false,"statusText":"statusText"}`); assert.calledOnce(_mockFetch); - - assert.calledOnce(showErrorMessage); - const showErrorMessageCalls = showErrorMessage.getCalls(); - expect(showErrorMessageCalls[0].args[0]).eq( - "Failed to fetch some files." - ); }); it("fetchDataFromDataverseAndUpdateVFS_whenResponseSuccessAndSubUriIsBlank_shouldThrowError", async () => { @@ -661,7 +677,6 @@ describe("remoteFetchProvider", () => { WebExtensionContext.telemetry, "sendErrorTelemetry" ); - const showErrorMessage = stub(vscode.window, "showErrorMessage"); stub(WebExtensionContext, "updateEntityDetailsInContext"); const sendAPITelemetry = stub( WebExtensionContext.telemetry, @@ -674,7 +689,6 @@ describe("remoteFetchProvider", () => { assert.calledOnce(_mockFetch); assert.calledTwice(sendAPITelemetry); assert.calledOnce(sendErrorTelemetry); - assert.calledOnce(showErrorMessage); assert.callCount(getEntity, 2); }); @@ -765,7 +779,6 @@ describe("remoteFetchProvider", () => { WebExtensionContext.telemetry, "sendErrorTelemetry" ); - const showErrorMessage = stub(vscode.window, "showErrorMessage"); stub(WebExtensionContext, "updateEntityDetailsInContext"); const sendAPITelemetry = stub( WebExtensionContext.telemetry, @@ -779,7 +792,6 @@ describe("remoteFetchProvider", () => { assert.calledOnce(_mockFetch); assert.calledTwice(sendAPITelemetry); assert.calledOnce(sendErrorTelemetry); - assert.calledOnce(showErrorMessage); assert.callCount(getEntity, 2); }); @@ -871,7 +883,6 @@ describe("remoteFetchProvider", () => { WebExtensionContext.telemetry, "sendErrorTelemetry" ); - const showErrorMessage = stub(vscode.window, "showErrorMessage"); stub(WebExtensionContext, "updateEntityDetailsInContext"); const sendAPITelemetry = stub( WebExtensionContext.telemetry, @@ -885,7 +896,6 @@ describe("remoteFetchProvider", () => { assert.calledOnce(_mockFetch); assert.calledTwice(sendAPITelemetry); assert.calledOnce(sendErrorTelemetry); - assert.calledOnce(showErrorMessage); assert.callCount(getEntity, 2); }); @@ -978,7 +988,6 @@ describe("remoteFetchProvider", () => { WebExtensionContext.telemetry, "sendErrorTelemetry" ); - const showErrorMessage = stub(vscode.window, "showErrorMessage"); const sendAPITelemetry = stub( WebExtensionContext.telemetry, "sendAPITelemetry" @@ -991,7 +1000,6 @@ describe("remoteFetchProvider", () => { assert.calledOnce(_mockFetch); assert.calledTwice(sendAPITelemetry); assert.calledOnce(sendErrorTelemetry); - assert.calledOnce(showErrorMessage); assert.callCount(getEntity, 2); });