Http request exception handling (#1743)

* add some exception handling and helpful error logging to failed http requests

* add simple test

* addressed pr comments: updated error messages and use environment.newline
This commit is contained in:
Paul Dorsch 2022-12-16 09:22:21 -05:00 коммит произвёл GitHub
Родитель 129fb6e0c8
Коммит 9624bd2bff
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
5 изменённых файлов: 61 добавлений и 8 удалений

Просмотреть файл

@ -152,5 +152,5 @@ path, removing `/home/site/wwwroot` from it.
When using App Service with a Virtual Network or an App Service Environment, you will need to allow outbound access
from the webapp to `oryx-cdn.microsoft.io` on port `443`. `oryx-cdn.microsoft.io` hosts the Oryx packages corresponding
to each SDK language and version. If this network dependency is blocked, then App Servicewill not be able to build your
to each SDK language and version. If this network dependency is blocked, then App Service will not be able to build your
application using Oryx.

Просмотреть файл

@ -33,5 +33,9 @@ namespace Microsoft.Oryx.BuildScriptGenerator
public const string BenvDynamicInstallRootDirKey = "dynamic_install_root_dir";
public const string BuildConfigurationFileHelp = "https://aka.ms/troubleshoot-buildconfig";
public const string NetworkConfigurationHelpText = "Please ensure that your " +
"network configuration allows traffic to required Oryx dependencies, as documented in " +
"'https://github.com/microsoft/Oryx/blob/main/doc/hosts/appservice.md#network-dependencies'";
}
}

Просмотреть файл

@ -2,7 +2,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
// --------------------------------------------------------------------------------------------
using System;
using System.Linq;
using System.Net.Http;
using System.Xml.Linq;
using Microsoft.Oryx.BuildScriptGenerator.Common;
@ -10,14 +12,31 @@ namespace Microsoft.Oryx.BuildScriptGenerator
{
internal static class ListBlobsHelper
{
public static XDocument GetAllBlobs(string sdkStorageBaseUrl, string platform, System.Net.Http.HttpClient httpClient, string oryxSdkStorageAccountAccessToken)
public static XDocument GetAllBlobs(string sdkStorageBaseUrl, string platform, HttpClient httpClient, string oryxSdkStorageAccountAccessToken)
{
var oryxSdkStorageAccountAccessArgs = oryxSdkStorageAccountAccessToken?.TrimStart(new char[] { '?' }) ?? string.Empty;
var url = string.Format(SdkStorageConstants.ContainerMetadataUrlFormat, sdkStorageBaseUrl, platform, string.Empty, oryxSdkStorageAccountAccessArgs);
var blobList = httpClient
string blobList;
try
{
blobList = httpClient
.GetStringAsync(url)
.Result;
}
catch (AggregateException ae)
{
throw new AggregateException(
$"Http request to retrieve the SDKs available to download from '{sdkStorageBaseUrl}' " +
$"failed. {Constants.NetworkConfigurationHelpText}{Environment.NewLine}{ae}");
}
if (string.IsNullOrEmpty(blobList))
{
throw new InvalidOperationException(
$"Http request to retrieve the SDKs available to download from'{sdkStorageBaseUrl}' cannot return an empty result.");
}
var xdoc = XDocument.Parse(blobList);
var marker = xdoc.Root.Element("NextMarker").Value;

Просмотреть файл

@ -8,6 +8,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using System.Xml.XPath;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
@ -97,9 +98,25 @@ namespace Microsoft.Oryx.BuildScriptGenerator
this.logger.LogDebug("Getting the default version from url {defaultVersionUrl}.", defaultVersionUrl);
// get default version
var defaultVersionContent = httpClient
string defaultVersionContent;
try
{
defaultVersionContent = httpClient
.GetStringAsync($"{defaultVersionUrl}{this.commonOptions.OryxSdkStorageAccountAccessToken}")
.Result;
}
catch (AggregateException ae)
{
throw new AggregateException(
$"Http request to retrieve the default version from '{defaultVersionUrl}' failed. " +
$"{Constants.NetworkConfigurationHelpText}{Environment.NewLine}{ae}");
}
if (string.IsNullOrEmpty(defaultVersionContent))
{
throw new InvalidOperationException(
$"Http request to retrieve the default version from '{defaultVersionUrl}' cannot return an empty result.");
}
string defaultVersion = null;
using (var stringReader = new StringReader(defaultVersionContent))

Просмотреть файл

@ -23,6 +23,8 @@ namespace Oryx.Integration.Tests
public abstract class StorageAccountSanityTestBase
: PlatformEndToEndTestsBase, IClassFixture<RepoRootDirTestFixture>
{
private const string _fakeStorageUrl = "https://oryx-cdn-fake.microsoft.io";
private readonly string _storageUrl;
private readonly string _repoRootDir;
private readonly string _sdkStorageAccountAccessToken;
@ -171,6 +173,17 @@ namespace Oryx.Integration.Tests
AssertExpectedDefaultVersion("maven", "java", "maven");
}
[Fact]
public void Throws_CorrectHttpErrorMessage()
{
// Act
var error = Assert.Throws<AggregateException>(() =>
ListBlobsHelper.GetAllBlobs(_fakeStorageUrl, "dotnet", _httpClient, _sdkStorageAccountAccessToken));
// Assert
Assert.Contains(Microsoft.Oryx.BuildScriptGenerator.Constants.NetworkConfigurationHelpText, error.Message);
}
private void AssertExpectedDefaultVersion(string platformName, params string[] expectedPlatformPath)
{
foreach (var debianFlavor in _debianFlavors)