Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[API Proposal]: udate QuicError values #87259

Closed
wfurt opened this issue Jun 8, 2023 · 7 comments · Fixed by #88234
Closed

[API Proposal]: udate QuicError values #87259

wfurt opened this issue Jun 8, 2023 · 7 comments · Fixed by #88234
Assignees
Labels
api-approved API was approved in API review, it can be implemented area-System.Net.Quic breaking-change Issue or PR that represents a breaking API or functional change over a prerelease. needs-breaking-change-doc-created Breaking changes need an issue opened with https://github.com/dotnet/docs/issues/new?template=dotnet
Milestone

Comments

@wfurt
Copy link
Member

wfurt commented Jun 8, 2023

Background and motivation

This is primarily driven by #75115 and #82262.

As noted in #75115, AcceptConnectionAsync can throw various exceptions and it is not obvious how they should be handled. For one, Quic also surfaces exceptions from user callback directly and that may make then indistinguishable from exceptions thrown by Quic itself - ODE may be particularly trick as leaked ODE exception from the callback may stop the server as it may look like whole listener was disposed. To make that more obvious, this issue is proposing to add new enum value and wrap anything from user callbacks in separate QuicException. #75184 originally proposed new enum specific to accept. However, after some discussion the user callback remains only one problematic and it is also conceptually valid to 'ConnectAsync`.

The second part of this proposal is based on API review board feedback on #76435. We wanted to add QuicError.AddressNotAvailable but the feedback was that is looks just like SocketError. As part of #82262 we agreed to throw SocketException for conditions that are not specific to Quic protocol and are caused by network conditions or environment configuration. That make several existing QuicError values obsolete and they would be never used. The proposal is to remove them - this is breaking change but we feel it is best long term option given that Quic still has preview flag.

API Proposal

namespace System.Net.Quic
{

    public enum QuicError
    {
        // existing members omitted

+       /// <summary>
+       /// An error occurred in user provided callback.
+       /// </summary>
+      UserCallbackError,
    }
}
    public enum QuicError
    {
        // existing members omitted

-      AddressInUse,
-      InvalidAddress,
-      HostUnreachable, // ICMP error
    }

API Usage

from #75115 Kestrel fragment

while (true)
{
    try
    {
        var connection = await _listener.AcceptConnectionAsync();
        return connection;
    }
    catch (ObjectDisposedException)
    {
        return null;
    }
    catch (QuicException ex)
    {
        // retry 
        log($"Quic failure {ex.Message} {ex.ErrorCode}");
    }
    catch (ArgumentException)
    {
        // retry
    }
}

Alternative Designs

#75184 originally proposed to add QuicError.AcceptConnectionFailed.

For the removal, we may mark the extra values as obsolete or we can keep them unused.

Risks

The proposed removal is breaking change. I tried to search but I did not find code that would explicitly handle the transport error codes.

@wfurt wfurt added api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Net.Quic labels Jun 8, 2023
@wfurt wfurt added this to the 8.0.0 milestone Jun 8, 2023
@wfurt wfurt self-assigned this Jun 8, 2023
@ghost
Copy link

ghost commented Jun 8, 2023

Tagging subscribers to this area: @dotnet/ncl
See info in area-owners.md if you want to be subscribed.

Issue Details

Background and motivation

This is primarily driven by #75115 and #82262.

As noted in #75115, AcceptConnectionAsync can throw various exceptions and it is not obvious how they should be handled. For one, Quic also surfaces exceptions from user callback directly and that may make then indistinguishable from exceptions thrown by Quic itself - ODE may be particularly trick as leaked ODE exception from the callback may stop the server as it may look like whole listener was disposed. To make that more obvious, this issue is proposing to add new enum value and wrap anything from user callbacks in separate QuicException. #75184 originally proposed new enum specific to accept. However, after some discussion the user callback remains only one problematic and it is also conceptually valid to 'ConnectAsync`.

The second part of this proposal is based on API review board feedback on #76435. We wanted to add QuicError.AddressNotAvailable but the feedback was that is looks just like SocketError. As part of #82262 we agreed to throw SocketException for conditions that are not specific to Quic protocol and are caused by network conditions or environment configuration. That make several existing QuicError values obsolete and they would be never used. The proposal is to remove them - this is breaking change but we feel it is best long term option given that Quic still has preview flag.

API Proposal

    public enum QuicError
    {
        // existing members omitted

+       /// <summary>
+       /// An error occurred in user provided callback.
+       /// </summary>
+      UserCallbackError,
    }
    public enum QuicError
    {
        // existing members omitted

-      AddressInUse,
-      InvalidAddress,
-      HostUnreachable, // ICM error
    }

API Usage

from #75115 Kestrel fragment

while (true)
{
    try
    {
        var connection = await _listener.AcceptConnectionAsync();
        return connection;
    }
    catch (ObjectDisposedException)
    {
        return null;
    }
    catch (QuicException ex)
    {
        // retry 
    }
    catch (ArgumentException)
    {
        // retry
    }
}

Alternative Designs

#75184 originally proposed to add QuicError.AcceptConnectionFailed.

For the removal, we may mark the extra values as obsolete or we can keep them unused.

Risks

The proposed removal is breaking change. I tried to search but I did not find code that would explicitly handle the transport error codes.

Author: wfurt
Assignees: wfurt
Labels:

api-suggestion, area-System.Net.Quic

Milestone: 8.0.0

@rzikm
Copy link
Member

rzikm commented Jun 8, 2023

It seems slightly confusing that the new enum value is not used in the API usage fragment.

@wfurt
Copy link
Member Author

wfurt commented Jun 8, 2023

It seems slightly confusing that the new enum value is not used in the API usage fragment.

That is partially by design. Back to discussion in #75115 all QuicExceptions will be retryable e.g. there is no need to handle specific error codes. I updated the example to log the ErrorCode for diagnostic reasons.

@wfurt wfurt added api-ready-for-review API is ready for review, it is NOT ready for implementation and removed api-suggestion Early API idea and discussion, it is NOT ready for implementation labels Jun 12, 2023
@bartonjs bartonjs added the breaking-change Issue or PR that represents a breaking API or functional change over a prerelease. label Jun 22, 2023
@ghost ghost added the needs-breaking-change-doc-created Breaking changes need an issue opened with https://github.com/dotnet/docs/issues/new?template=dotnet label Jun 22, 2023
@ghost
Copy link

ghost commented Jun 22, 2023

Added needs-breaking-change-doc-created label because this issue has the breaking-change label.

  1. Create and link to this issue a matching issue in the dotnet/docs repo using the breaking change documentation template, then remove this needs-breaking-change-doc-created label.

Tagging @dotnet/compat for awareness of the breaking change.

@bartonjs
Copy link
Member

bartonjs commented Jun 22, 2023

Video

  • The "User" prefix on UserCallbackError doesn't seem significant, so changed to just "CallbackError"
  • The removed items should be documented as a preview breaking change.
namespace System.Net.Quic
{
    public enum QuicError
    {
        // existing members omitted

+       /// <summary>
+       /// An error occurred in user provided callback.
+       /// </summary>
+       CallbackError,

-       AddressInUse,
-       InvalidAddress,
-       HostUnreachable, // ICMP error
    }
}

@bartonjs bartonjs added api-approved API was approved in API review, it can be implemented and removed api-ready-for-review API is ready for review, it is NOT ready for implementation labels Jun 22, 2023
@halter73
Copy link
Member

Since we said that only the Quic implementation has reason to construct a QuicException when comparing this to #75184, should we remove the existing public constructor on QuicException?

@rzikm Did you have a particular reason for wanting the new constructor to be public?

@rzikm
Copy link
Member

rzikm commented Jun 23, 2023

The idea was to enable unit-testing scenarios (i.e. enable mocking code construct QuicExceptions with the same innerExceptions as are thrown from System.Net.Quic).

@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Jun 30, 2023
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Jun 30, 2023
@dotnet dotnet locked as resolved and limited conversation to collaborators Jul 30, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api-approved API was approved in API review, it can be implemented area-System.Net.Quic breaking-change Issue or PR that represents a breaking API or functional change over a prerelease. needs-breaking-change-doc-created Breaking changes need an issue opened with https://github.com/dotnet/docs/issues/new?template=dotnet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants