diff --git a/release_notes.md b/release_notes.md index 26e0796f2..a0d7dcab3 100644 --- a/release_notes.md +++ b/release_notes.md @@ -24,4 +24,5 @@ - Support for custom bundle download paths via `AzureFunctionsJobHost__extensionBundle__downloadPath` environment variable - Added `--bundles-channel` option to `func init` command to specify extension bundle channel (GA, Preview, or Experimental) during project initialization - Fallback to cached bundles if there is no network connection during `func start` (#4772) - - Added global `--offline` variable to run in offline mode (#4772) +- Added global `--offline` variable to run in offline mode (#4772) +- Improved error message for `func azure functionapp publish` when the connection fails due to networking restrictions, with a link to networking options documentation. (#4807) \ No newline at end of file diff --git a/src/Cli/func/Actions/AzureActions/PublishFunctionAppAction.cs b/src/Cli/func/Actions/AzureActions/PublishFunctionAppAction.cs index ffda793ed..f7ecbfc5e 100644 --- a/src/Cli/func/Actions/AzureActions/PublishFunctionAppAction.cs +++ b/src/Cli/func/Actions/AzureActions/PublishFunctionAppAction.cs @@ -2,6 +2,7 @@ // Licensed under the MIT License. See LICENSE in the project root for license information. using System.Globalization; +using System.Net.Http; using System.Net.Http.Handlers; using System.Net.Http.Headers; using Azure.Functions.Cli.Actions.LocalActions; @@ -240,13 +241,22 @@ public override async Task RunAsync() } else { - if (PublishLocalSettingsOnly) + try { - await PublishLocalAppSettings(functionApp, additionalAppSettings); + if (PublishLocalSettingsOnly) + { + await PublishLocalAppSettings(functionApp, additionalAppSettings); + } + else + { + await PublishFunctionApp(functionApp, ignoreParser, additionalAppSettings); + } } - else + catch (HttpRequestException ex) { - await PublishFunctionApp(functionApp, ignoreParser, additionalAppSettings); + // HttpRequestException is thrown for connectivity failures (SSL, socket, DNS) + // not for HTTP status errors, which are handled by CheckResponseStatusAsync as CliException. + throw new CliException($"{Constants.Errors.PublishNetworkingError}{Environment.NewLine}Details: {ex.Message}", ex); } } } diff --git a/src/Cli/func/Common/Constants.cs b/src/Cli/func/Common/Constants.cs index ceff72d24..822a8d715 100644 --- a/src/Cli/func/Common/Constants.cs +++ b/src/Cli/func/Common/Constants.cs @@ -143,6 +143,7 @@ public static class Errors public const string EitherPidOrAllMustBeSpecified = "Must specify either -a/--all or -p/--processId "; public const string ExtensionsNeedDotnet = "Extensions command requires dotnet on your path. Please make sure to install dotnet (.NET Core SDK) for your system from https://www.microsoft.com/net/download"; public const string UnableToUpdateAppSettings = "Error updating Application Settings for the Function App for deployment."; + public const string PublishNetworkingError = "Unable to connect to the Azure Function App. If public network access is disabled for this app, ensure you are deploying from an authorized network. For more information, see https://learn.microsoft.com/azure/azure-functions/functions-networking-options"; public const string WebJobsStorageNotFound = "Missing value for AzureWebJobsStorage in {0}. This is required for all triggers other than {1}. You can run 'func azure functionapp fetch-app-settings ' or specify a connection string in {2}."; public const string WebJobsStorageNotFoundWithUserSecrets = "Missing value for AzureWebJobsStorage in {0} and User Secrets. This is required for all triggers other than {1}. You can run 'func azure functionapp fetch-app-settings ' or specify a connection string in {2} or User Secrets."; public const string AppSettingNotFound = "Warning: Cannot find value named '{0}' in {1} that matches '{2}' property set on '{3}' in '{4}'. You can run 'func azure functionapp fetch-app-settings ' or specify a connection string in {5}.";