镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

API Proposal: UnreachableException #35324

Closed

Description

@carlreinke

Motivation

This exception is expected to never be thrown. Code coverage tools might choose to ignore non-coverage of the statement or branch that throws this exception. In fact, coverage of such a statement or branch is undesirable, as it would indicate that the code is making an invalid assumption.

Proposal

#nullable enable
using System.Runtime.Serialization;

namespace System
{
    public sealed class UnreachableException : SystemException
    {
        public UnreachableException()
            : base("The program executed an instruction that was thought to be unreachable.")
        {
        }

        public UnreachableException(string? message)
            : base(message)
        {
        }

        public UnreachableException(string? message, Exception? innerException)
            : base(message, innerException)
        {
        }

        private UnreachableException(SerializationInfo info, StreamingContext context)
            : base(info, context)
        {
        }
    }
}

See Also

Activity

  1. added
    api-suggestionEarly API idea and discussion, it is NOT ready for implementation
    on Apr 23, 2020
  2. removed
    untriagedNew issue has not been triaged by the area owner
    on Jul 7, 2020
  3. added this to the Future milestone on Jul 7, 2020
  4. carlreinke commented on Aug 18, 2020

    @carlreinke
    ContributorAuthor

    @bartonjs @joperezr Any concerns or can this be ready-for-review?

  5. GrabYourPitchforks commented on Aug 19, 2020

    @GrabYourPitchforks
    Member

    How would this interact with the proposed "never" return type (dotnet/csharplang#538)? Is this API a point-in-time patch until that feature comes online?

    Presumably code coverage analyzers could already look for methods marked with [DoesNotReturn] and exclude any code after such call sites from being included in the final metrics.

    It would be helpful to clarify this exception's place in the ecosystem in a world where both of these capabilities exist.

  6. carlreinke commented on Aug 19, 2020

    @carlreinke
    ContributorAuthor

    [DoesNotReturn] and "never" do not apply in a lot of cases where UnreachableException would be used.

    Consider a random example taken from Roslyn:
    https://github.com/dotnet/roslyn/blob/e704ca635bd6de70a0250e34c4567c7a28fa9f6d/src/Compilers/CSharp/Portable/Binder/BlockBinder.cs#L64-L72

    In this case, the method does sometimes return (in fact, if the unreachability assumption is correct, it always returns), so neither [DoesNotReturn] nor "never" are applicable to that method, yet there is a code path that is expected to be unreachable.

    Applying [DoesNotReturn] or "never" to an "Unreachable" helper method and calling that instead doesn't solve the problem because that helper method still has to throw some exception to indicate that the presumably unreachable code path was executed (or it could FailFast, but that's not what you want in a lot of cases).

    Also, code coverage should expect not to cover the throw new UnreachableException() statement itself, not code following it. Any code following it would already be considered unreachable by the compiler's reachability analysis by nature of an exception being thrown.

    It would actually also be the reverse -- any code on a code path that inevitably leads to throw new UnreachableException() can be considered "unreachable" for code coverage purposes. (Though I'm not suggesting anything would or even should do that analysis.)

  7. GSPP commented on Nov 17, 2020

    @GSPP

    This seems very useful to me. Sometimes, a code location is to be considered unreachable. Having this exception type confers the following benefits:

    1. It documents intent.
    2. It makes C# flow analysis understand that this point in the code does not continue execution.
    3. If this is ever reached at runtime due to a bug, the algorithm aborts. Presumably, control transfers to some generic top-level exception handler that logs the exception and alerts developers.
    4. Resharper could be taught to understand what this type means.
    5. Having this in the BCL creates an ecosystem-wide standard.

    Adding this type would not be a complicated change. It can easily be trimmed. The assembly size increase would be modest.

    I have defined this type myself and I'm using it.

  8. carlreinke commented on Feb 18, 2021

    @carlreinke
    ContributorAuthor

    @GrabYourPitchforks Any other concerns or can this be put into the review queue?

  9. added
    api-ready-for-reviewAPI is ready for review, it is NOT ready for implementation
    and removed
    api-suggestionEarly API idea and discussion, it is NOT ready for implementation
    on Apr 21, 2021
  10. GrabYourPitchforks commented on Apr 21, 2021

    @GrabYourPitchforks
    Member

    Marking this as ready for review.

    Open question for reviewers: given that the target scenario is for debugging, code coverage, and other dev tools; would System.Diagnostics be a more appropriate namespace than System?

  11. marek-safar commented on Apr 21, 2021

    @marek-safar
    Contributor

    I like this and it'd be also useful for tools like IL linker which have to now uses NotSupportedException with a string explanation that the body is unreachable.

  12. bartonjs commented on Apr 21, 2021

    @bartonjs
    Member

    System.Diagnostics feels more appropriate to me. In all the cases I'd see myself using it I currently have a Debug.Fail, then the exception so the compiler doesn't tell me my execution flow makes no sense.

    If we end up doing a public ThrowHelper-type API for ArgumentNullException (#48573) then we'd probably want one here, too.

  13. 24 remaining items

  14. bartonjs commented on Jan 18, 2022

    @bartonjs
    Member

    The PR observed that there were still some floating points. Marking as review-ready and blocking so we discuss them today to unblock the PR.

  15. added
    api-ready-for-reviewAPI is ready for review, it is NOT ready for implementation
    blockingMarks issues that we want to fast track in order to unblock other important work
    and removed
    api-approvedAPI was approved in API review, it can be implemented
    on Jan 18, 2022
  16. deeprobin commented on Jan 18, 2022

    @deeprobin
    Contributor

    The PR observed that there were still some floating points. Marking as review-ready and blocking so we discuss them today to unblock the PR.

    Great 👍🏼!

    Is this a small change (i.e. just implement the API + tests) or are there other changes that need to be made?

  17. bartonjs commented on Jan 18, 2022

    @bartonjs
    Member

    Video

    We seem to have hit the most agreeable (perhaps "least disagreeable") position with System.Diagnostics, on the basis that it's rather like an assert (System.Diagnostics.Debug.Assert); and based on @jkotas feedback, the exception isn't really special... so : Exception instead of : SystemException.

    namespace System.Diagnostics
    {
        public sealed class UnreachableException : Exception
        {
            public UnreachableException()
                : base("The program executed an instruction that was thought to be unreachable.")
            {
            }
    
            public UnreachableException(string? message)
                : base(message)
            {
            }
    
            public UnreachableException(string? message, Exception? innerException)
                : base(message, innerException)
            {
            }
        }
    }
  18. added
    api-approvedAPI was approved in API review, it can be implemented
    and removed
    api-ready-for-reviewAPI is ready for review, it is NOT ready for implementation
    blockingMarks issues that we want to fast track in order to unblock other important work
    on Jan 18, 2022
  19. deeprobin commented on Jan 18, 2022

    @deeprobin
    Contributor

    Since this is only a small change, I'm happy to work on that issue.

  20. stephentoub commented on Jan 18, 2022

    @stephentoub
    Member

    Since this is only a small change, I'm happy to work on that issue.

    There's already an in-flight PR for it.

  21. jstaro commented on Jan 18, 2022

    @jstaro

    I know this is a bit late, but I was surprised the discussion didn't float the idea that this exception is quite similar (at least in my mind) in concept to NotImplementedException which lives in the System namespace.

  22. ghost removed
    in-prThere is an active PR which will close this issue when it is merged
    on Jan 26, 2022
  23. ghost locked as resolved and limited conversation to collaborators on Feb 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions