Skip to content

Comments

ArgumentOutOfRangeException throw helpers#69767

Closed
hrrrrustic wants to merge 25 commits intodotnet:mainfrom
hrrrrustic:outOfRange
Closed

ArgumentOutOfRangeException throw helpers#69767
hrrrrustic wants to merge 25 commits intodotnet:mainfrom
hrrrrustic:outOfRange

Conversation

@hrrrrustic
Copy link
Contributor

@hrrrrustic hrrrrustic commented May 25, 2022

Converting usages to possible new helpers (#69590) without /tests directories
It's possible that this PR contains a few wrong conversions/casts/bugs, but I'll fix them in smaller PRs after approving API. This one is just for collecting statistic

Did not find any meaningful custom messages and dropped them all for now. But can be revisited more carefully in smaller separate PRs. ThrowIf method should contains additional message argument that I will add in separate PRs (Just need to regenerate all this diff and don't drop messages from old throwing) It can't have it as lazy. ThrowIf will be removed it separate PRs

The main problem is that all tests with Assert.Throws( () => {}) verifies paramName (that's ok). But if some cast was used while passing argument to helper it will also appear in paramName and fail the test (e.g (uint) index)

Remaining manual throwing:

  1. else if (...) throw OutOfRange else
  2. Custom ThrowHelpers
  3. Something between if and throw (Debug.Fail or logging)
  4. switch-case with default
  5. Usages under net4.x/netstandard targets

Main (search for /libraries):
image

This PR:
image

@ghost ghost added community-contribution Indicates that the PR has been added by a community member area-Meta new-api-needs-documentation labels May 25, 2022
@ghost
Copy link

ghost commented May 25, 2022

Note regarding the new-api-needs-documentation label:

This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, to please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change.

@ghost
Copy link

ghost commented May 25, 2022

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

Issue Details

Converting usages to possible new helpers (#69590) without /tests directories
Changed a little bit generic constraints in suggested methods due to some generic math interfaces were moved
Did not find any meaningful custom messages and dropped them all for now

Compilation errors:

  • A little bit cases with pointers (I'll remove them manually)
  • Some usages with TimeSpan, Decimal, DateTime, etc. The IComparisonOperators<TSelf, TSelf> interface removed via Determine recommended behavior of checked/unchecked operators for DateTime and similar types #67744. But I actually don't understand how exactly IComparisonOperators<TSelf, TSelf> related to overflowing and checked / unchecked. @tannergooding
  • A lot of usages with enums for IsNotBetween. I tried to mark them all with "ENUMUSAGE" message argument
  • I also added (or removed) manual casting to uint a few times

Remaining manual throwing:

  1. More complex conditions that could be converted to the proposed API manually
  2. A lot of custom conditions, maybe it would make sense to add ThrowIf(bool condition... overload
  3. arg < someValue || arg >= someValue. This is really close to IsNotBetween, but not enough 😄
  4. else if () throw OutOfRange or if () throw OutOfRange; else. Could be converted manually by removing if/else at all
  5. Some GreaterOrEqualsThan and LessOrEqualsThan cases
  6. Custom ThrowHelpers
  7. Something between if and throw (Debug.Fail or logging)
  8. Throwing in switch-case

Main (search for /libraries):
image

This PR:
image

Author: hrrrrustic
Assignees: -
Labels:

area-Meta, new-api-needs-documentation, community-contribution

Milestone: -

@jeffhandley jeffhandley self-assigned this May 29, 2022
@jeffhandley
Copy link
Member

@hrrrrustic I assigned myself to ensure you get a review on this once the build errors are fixed.

@hrrrrustic
Copy link
Contributor Author

I'll try to finish work this week. Converting to draft for now

@hrrrrustic hrrrrustic marked this pull request as draft June 6, 2022 10:23
@hrrrrustic
Copy link
Contributor Author

hrrrrustic commented Jun 27, 2022

Jobs are still failing, some errors can be fixed by reverting changes in old libraries, others related to ParamName (described it in first comment)
Since this PR should be splitted in smaller parts anyway, I hope this is enough at least for initial review in #69590

@hrrrrustic hrrrrustic marked this pull request as ready for review June 27, 2022 01:43
{
throw new ArgumentOutOfRangeException(nameof(value));
}
ArgumentOutOfRangeException.ThrowIfNotBetween(value, 0, int.MaxValue);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ThrowIfNotBetween suggests an exclusive range, but the code here treated the ends of the range as valid. Should it be something like ThrowIfOutsideRange?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initially discussed here
#69590 (comment)

But can be easily changed to ThrowIfOutsideRange. Added this to questions section in issue

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ThrowIfNotBetween is perhaps a good name, but i think it would not be the method you use here. Anyway, as you say, naming can be discussed at review.

{
throw new ArgumentOutOfRangeException(nameof(segment));
}
ArgumentOutOfRangeException.ThrowIf(segment.Offset < 0 || segment.Count < 0 || segment.Count > (segment.Array.Length - segment.Offset));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This no longer includes the argument name.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see you mentioned that, but it would be good to fix to see what it looks like.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, I'll add message (or paramName) arg to ThrowIf after regenerating diff. Just not sure should it be simple string or interpolation handler. Mentioned that in linked issue


ArgumentOutOfRangeException.ThrowIfLessThan(bytes.Length - byteIndex, byteCount);

ArgumentOutOfRangeException.ThrowIfLessThan(chars.Length - charIndex, charCount);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some relatively simple checks here turned into a lot of method calls - maybe inlined - is the generated code larger?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't check that, what's the easiest way to do that?
Also current implementation should use same private helper as ArgumentNullException for better inlining I guess

[DoesNotReturn]
internal static void Throw(string? paramName) =>
throw new ArgumentNullException(paramName);

@eerhardt
Copy link
Member

Closing per https://github.com/dotnet/runtime/blob/main/docs/project/api-review-process.md#pull-requests. We can reopen this PR once the API has been approved.

@eerhardt eerhardt closed this Jul 25, 2022
@hrrrrustic
Copy link
Contributor Author

Closing per https://github.com/dotnet/runtime/blob/main/docs/project/api-review-process.md#pull-requests. We can reopen this PR once the API has been approved.

This PR was created to address #69590 (comment), but I think it's ok to close it until api review process

@stephentoub
Copy link
Member

This PR was created to address #69590 (comment),

Thanks. We don't actually need a PR for that, since we can't "pull" anything until the APIs are approved. The goal of doing the work is to be able to tweak the APIs into they're as successful as possible, which can be done just with local changes and a commit linked from the API issue. I appreciate your efforts here.

@ghost ghost locked as resolved and limited conversation to collaborators Aug 25, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-Meta community-contribution Indicates that the PR has been added by a community member new-api-needs-documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants