diff --git a/package-lock.json b/package-lock.json index b0028e3f8..90f314516 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,6 +24,7 @@ "@microsoft/vscode-azext-azureutils": "^2.0.1", "@microsoft/vscode-azext-utils": "^2.0.0", "@microsoft/vscode-azureresources-api": "^2.0.4", + "cross-fetch": "^4.0.0", "escape-string-regexp": "^4.0.0", "extract-zip": "^2.0.1", "fs-extra": "^4.0.2", @@ -3670,6 +3671,14 @@ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, + "node_modules/cross-fetch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", + "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", + "dependencies": { + "node-fetch": "^2.6.12" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -16107,6 +16116,14 @@ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, + "cross-fetch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", + "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", + "requires": { + "node-fetch": "^2.6.12" + } + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", diff --git a/package.json b/package.json index f87c00f9d..7bb3077c3 100644 --- a/package.json +++ b/package.json @@ -1156,6 +1156,7 @@ "@microsoft/vscode-azext-azureutils": "^2.0.1", "@microsoft/vscode-azext-utils": "^2.0.0", "@microsoft/vscode-azureresources-api": "^2.0.4", + "cross-fetch": "^4.0.0", "escape-string-regexp": "^4.0.0", "extract-zip": "^2.0.1", "fs-extra": "^4.0.2", diff --git a/src/commands/executeFunction.ts b/src/commands/executeFunction.ts index d3286fd80..c17cf609d 100644 --- a/src/commands/executeFunction.ts +++ b/src/commands/executeFunction.ts @@ -6,6 +6,7 @@ import { createHttpHeaders } from '@azure/core-rest-pipeline'; import { SiteClient } from '@microsoft/vscode-azext-azureappservice'; import { IActionContext, parseError } from '@microsoft/vscode-azext-utils'; +import fetch from 'cross-fetch'; import { window } from 'vscode'; import { FuncVersion } from '../FuncVersion'; import { functionFilter } from '../constants'; @@ -82,10 +83,15 @@ export async function executeFunction(context: IActionContext, node?: FunctionTr context.errorHandling.suppressReportIssue = true; throw new Error(localize('failedToConnect', 'Failed to connect. Make sure your project is [running locally](https://aka.ms/AA76v2d).')); } else if (errorType === '400') { - // stringify JSON object to match the format in the portal - functionInput = <{}>JSON.stringify(functionInput, undefined, 2); - body = { input: functionInput }; - responseText = (await requestUtils.sendRequestWithExtTimeout(context, { method: 'POST', ...triggerRequest, headers, body: JSON.stringify(body) })).bodyAsText; + const response = await fetch(triggerRequest.url, { + method: 'POST', + body: JSON.stringify({ + // stringify JSON object to match the format in the portal + input: JSON.stringify(functionInput), + }), + headers: headers.toJSON(), + }); + responseText = await response.text(); } else { context.telemetry.maskEntireErrorMessage = true; // since the response is directly related to the code the user authored themselves throw error; diff --git a/test/nightly/createProjectAndDeploy.test.ts b/test/nightly/createProjectAndDeploy.test.ts index d8d996140..f2f43b285 100644 --- a/test/nightly/createProjectAndDeploy.test.ts +++ b/test/nightly/createProjectAndDeploy.test.ts @@ -13,7 +13,7 @@ import * as vscode from 'vscode'; import { copyFunctionUrl, createGenericClient, createNewProjectInternal, deployProductionSlot, FuncVersion, getRandomHexString, nonNullProp } from '../../extension.bundle'; import { addParallelSuite, ParallelTest, runInSeries } from '../addParallelSuite'; import { getTestWorkspaceFolder } from '../global.test'; -import { defaultTestFuncVersion, getCSharpValidateOptions, getJavaScriptValidateOptions, getBallerinaValidateOptions, getPowerShellValidateOptions, getPythonValidateOptions, getTypeScriptValidateOptions, IValidateProjectOptions, validateProject } from '../project/validateProject'; +import { defaultTestFuncVersion, getBallerinaValidateOptions, getCSharpValidateOptions, getJavaScriptValidateOptions, getPowerShellValidateOptions, getPythonValidateOptions, getTypeScriptValidateOptions, IValidateProjectOptions, validateProject } from '../project/validateProject'; import { getRotatingAuthLevel, getRotatingLocation, getRotatingNodeVersion, getRotatingPythonVersion } from './getRotatingValue'; import { resourceGroupsToDelete } from './global.nightly.test'; @@ -120,7 +120,7 @@ async function validateFunctionUrl(appName: string, functionName: string, routeP assert.ok(functionUrl?.includes(routePrefix), `Function url "${functionUrl}" did not include routePrefix "${routePrefix}".`); const client: ServiceClient = await createGenericClient(await createTestActionContext(), undefined); - const response = await client.sendRequest(createPipelineRequest({ method: 'POST', url: functionUrl!, body: { name: "World" } })); + const response = await client.sendRequest(createPipelineRequest({ method: 'POST', url: functionUrl!, body: JSON.stringify({ name: "World" }) })); const body: string = nonNullProp(response, 'bodyAsText'); assert.ok((body.includes('Hello') && body.includes('World')) || body.includes('Welcome'), 'Expected function response to include "Hello World" or "Welcome"'); }