如何捕获ExtendedSocketException?

7
这听起来很蠢,但我就是无法捕获由SocketTaskExtensions.ConnectAsync()抛出的ExtendedSocketException异常。
完整的名称空间为:System.Net.Internals.SocketExceptionFactory.ExtendedSocketException 编译器报错:Cannot resolve symbol 'ExtendedSocketException'。我的类库和测试项目都针对.NET Core 2.1。
此外,没有这样的引用或Nuget包可以添加。至少我找不到任何信息... 此外,在https://learn.microsoft.com上似乎也没有相关信息...
我在哪里做错了?
[Fact]
[Trait("Category", "UnitTest")]
public async Task Should_Throw_Exception_If_Port_Unreachable()
{
    // Arrange
    var client = new TcpConnector();
    var nonListeningPort = 81;
    var endpoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), nonListeningPort);

    // Act & Assert
    var connectTask = client.ConnectAsync(endpoint);
    Func<Task> func = async () => { await connectTask; };

    func.Should().Throw<ExtendedSocketException>();
}

你的问题不够清晰。异常是一个内部的.NET类型。虽然你可能会在调试器中遇到它,但你自己的代码不应该看到它。你为什么认为你应该看到它呢? - Peter Duniho
3个回答

10

ExtendedSocketException是一个private类,因此您无法在.NET内部以外引用它。但是,您可以捕获SocketException并检查异常消息。


1
不存在非嵌套的“私有类”。 - Peter Duniho
我知道它们。但是 System.Net.Internals.SocketExceptionFactory.ExtendedSocketException 不是一个嵌套类型。我坚持我的说法。我注意到 OP 的帖子可能不完全正确,因为他们可能想引用 System.Net.Internals.SocketExceptionFactory+ExtendedSocketException,这将是一个私有类。但是,如果您的意思是这样的话,那么您的“答案”(我使用这个词并不严谨)应该澄清这一点。 - Peter Duniho
@PeterDuniho 现在有了 :) - AgentFire

5
尽管“ExtendedSocketException”旨在保持私有,但它肯定被暴露出来了: ExtendedSocketException 另一方面,它继承自“SocketException”,因此我们不需要太在意它。
至于你的测试,我认为你应该能够将断言修改为类似以下内容:
var exception = Assert.Catch(func);
Assert.IsInstanceOf<SocketException>(exception);
Assert.That(exception.Message.Contains("actively refused"));

1

ExtendedSocketException 是从 SocketException 派生的(适用于 .NET Core)。这仍然可以通过使用捕获 SocketException 的 catch 块来处理。我们可以通过 System.Type.IsAssignableFrom(Type c) 来确认这一点:

catch (Exception e)
{
     Debug.Write(typeof(SocketException).IsAssignableFrom(e.GetType()));
}

在xUnit中,断言可以是:
var client = new TcpClient();
Task result() => client.ConnectAsync(IPAddress.Loopback, 23000);
var ex = Record.ExceptionAsync(async () => await client.ConnectAsync(IPAddress.Loopback, 23000));
Assert.IsAssignableFrom<SocketException>(ex.Result);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接