首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从httpClient引发的异常获取网络错误状态吗?

从httpClient引发的异常获取网络错误状态吗?
EN

Stack Overflow用户
提问于 2022-02-18 19:55:11
回答 1查看 762关注 0票数 2

我正在使用Blazor和dotnet6构建一个内部工具,它调用外部API。

Xunit中的极简示例--但假设这是从Blazor客户端运行的

代码语言:javascript
复制
[Xunit.Theory]
[InlineData("http://www.brokenexample.com/", "blocked for mixed-content")]
[InlineData("https://www.brokenexample.com/", "ERR_NAME_NOT_RESOLVED")]
[InlineData("https://www.api.with.cors.com/", "CORS Error")]
public async Task CanGetErrorMessage(string url, string expectedError)
{
    try
    {
        var httpClient = new HttpClient();
        var httpResponseMessage = await httpClient.GetAsync(url);
    }
    catch (Exception e)
    {
        var innerError = e.Message; // somehow find the inner error
        Assert.Equal(innerError, expectedError);
    }
}

chrome选项卡中“阻止混合内容”的屏幕截图:

铬网络选项卡中ERR_NAME_NOT_RESOLVED的屏幕截图:

铬网络选项卡中CORS错误的屏幕截图:

然而,我的e.Message总是

代码语言:javascript
复制
"TypeError: Failed to fetch"

而内在的例外总是

代码语言:javascript
复制
System.Runtime.InteropServices.JavaScript.JSException

具有相同的错误消息,并且没有进一步的内部异常。

因此,我猜Blazor正在与Javascript进行交互,这会抛出一个异常--也许Interop/代理客户机正在捕捉它,并且只返回"TypeError: fetch“

不知何故,我的(chrome)浏览器能够区分不同类型的连接错误,但“真正的”异常似乎没有出现在我的异常堆栈中的任何地方。

有时候,有一个Http-Statuscode是有点有用的,但任何失败的飞行前,如CORS或连接拒绝似乎都一样。

这个工具的目的是用户可以在运行时输入他们的URL并测试连接,所以我不能真正地预先确定会发生什么,以及连接是否会工作。

它是一个内部工具,所以我希望能够告诉我的最终用户:“这个url因为CORS而不能工作,您可以通过下载一个铬扩展名来禁用cors等等来修复它,以及更详细地解释某个url不能工作的原因,并帮助他们让它工作。

有没有办法获得这些屏幕截图中显示的状态信息?

EN

回答 1

Stack Overflow用户

发布于 2022-03-30 04:12:49

它的Chrome也不例外

如果这个细节有一个例外的话,那就太好了,不幸的是,没有一个当机立断地抓住细节(我已经试过了)。

代码语言:javascript
复制
catch (WebException exc)
{
    Console.WriteLine("Network Error: " + exc.Message + "\nStatus code: " + exc.Status);
}
catch (ProtocolViolationException exc)
{
    Console.WriteLine("Protocol Error: " + exc.Message);
}
catch (UriFormatException exc)
{
    Console.WriteLine("URI Format Error: " + exc.Message);
}
catch (NotSupportedException exc)
{
    Console.WriteLine("Unknown Protocol: " + exc.Message);
}
catch (IOException exc)
{
    Console.WriteLine("I/O Error: " + exc.Message);
}
catch (System.Security.SecurityException exc)
{
    Console.WriteLine("Security Exception: " + exc.Message);
}
catch (InvalidOperationException exc)
{
    Console.WriteLine("Invalid Operation: " + exc.Message);
}
catch (HttpRequestException exc)
{
    Console.WriteLine("Invalid Operation: " + exc.Message);
}
catch (Exception exc)
{
    Console.WriteLine("Invalid Operation: " + exc.Message);
}

使用Selenium4获取Chrome等选项卡

幸运的是,在最新发布的Selenium 4中,有一种方法就是使用Chrome来捕捉它。阅读更多内容:https://www.selenium.dev/documentation/webdriver/bidirectional/chrome_devtools/和/或本文,其中介绍了以前版本的技术:https://rahulshettyacademy.com/blog/index.php/2021/11/04/selenium-4-key-feature-network-interception/

您可以在这里下载驱动程序(与您的Chrome版本一致):http://chromedriver.storage.googleapis.com/index.html

  1. 解压缩ChromeDriver.exe并将其复制到Project\bin\Debug\net6.0文件夹

  1. Add Nuget Package Selenium.WebDriver 4.1 (或更高).

下面是我从Selenium4 4文档中的示例中修改的代码:https://www.selenium.dev/documentation/webdriver/bidirectional/chrome_devtools/

代码语言:javascript
复制
using System.Net;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.DevTools;

// We must use a version-specific set of domains
using OpenQA.Selenium.DevTools.V94.Performance;

var url = "https://www.brokenexample.com/";

IWebDriver driver = new ChromeDriver();
IDevTools devTools = driver as IDevTools;
DevToolsSession session = devTools.GetDevToolsSession();
//await session.SendCommand<EnableCommandSettings>(new EnableCommandSettings());
var metricsResponse =
    await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
        new GetMetricsCommandSettings());

try
{
    driver.Navigate().GoToUrl(url);
    driver.Quit();
}
catch (Exception ex)
{
    var innerError = ex.Message;
}

Selenium4断裂变化

你在网上找到的很多例子都是用Beta版本编写的,比如:https://dotjord.wordpress.com/2020/09/13/how-to-capture-network-activity-with-selenium-4-in-asp-net-core-3-1/

测试版(旧代码):

代码语言:javascript
复制
IDevTools devTools = driver as IDevTools;
DevToolsSession session = devTools.CreateDevToolsSession();
session.Network.ResponseReceived += ResponseReceivedHandler;
session.Network.Enable(new EnableCommandSettings());
driver.Navigate().GoToUrl(url);
public void ResponseReceivedHandler(object sender, ResponseReceivedEventArgs e)
{
    System.Diagnostics.Debug.WriteLine($"Status: { e.Response.Status } : {e.Response.StatusText} | File: { e.Response.MimeType } | Url: { e.Response.Url }");
}

阿尔法(工作代码):

代码语言:javascript
复制
using DevToolsSessionDomains = OpenQA.Selenium.DevTools.V96.DevToolsSessionDomains;
var driver = new ChromeDriver();
var devTools = (IDevTools)driver;
IDevToolsSession session = devTools.GetDevToolsSession();
var domains = session.GetVersionSpecificDomains<DevToolsSessionDomains>();
domains.Network.ResponseReceived += ResponseReceivedHandler;
await domains.Network.Enable(new OpenQA.Selenium.DevTools.V96.Network.EnableCommandSettings());
driver.Navigate().GoToUrl(url);

void ResponseReceivedHandler(object sender, ResponseReceivedEventArgs e)
{
    System.Diagnostics.Debug.WriteLine($"Status: { e.Response.Status } : {e.Response.StatusText} | File: { e.Response.MimeType } | Url: { e.Response.Url }");
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71179187

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档