Skip to content

Improve ValidateCount attribute error message - #3596

Merged
Dongbo Wang (daxian-dbw) merged 8 commits into
PowerShell:masterfrom
iSazonov:validatecount-message
Apr 22, 2017
Merged

Improve ValidateCount attribute error message#3596
Dongbo Wang (daxian-dbw) merged 8 commits into
PowerShell:masterfrom
iSazonov:validatecount-message

Conversation

@iSazonov

@iSazonov Ilya (iSazonov) commented Apr 19, 2017

Copy link
Copy Markdown
Collaborator

Fix #3585

@BrucePay Bruce Payette (BrucePay) left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

There's a typo in the error message. It should say "is not equal" - the "is" is missing.

@iSazonov

Copy link
Copy Markdown
Collaborator Author

Thanks! Typo is fixed.

<value>The number of provided arguments, ({1}), exceeds the maximum number of allowed arguments ({0}). Provide fewer than {0} arguments, and then try the command again.</value>
</data>
<data name="ValidateCountEqualLengthFailure" xml:space="preserve">
<value>The number of provided arguments, ({1}), is not equal the number of allowed arguments ({0}). Provide exactly {0} arguments, and then try the command again.</value>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is definitely better, but I'm finding all 3 error messages too wordy and slightly inaccurate. First, maybe we should change arguments to values because there is a single argument with multiple values.

Second, maybe 1 error message is sufficient if we change it to:

The parameter requires at least `{0}` value(s) and no more than `{1}` value(s) - `{2}` value(s) were provided.

@daxian-dbw

Dongbo Wang (daxian-dbw) commented Apr 20, 2017

Copy link
Copy Markdown
Member

I edited the changes to correct a typo and remove duplicate test cases.
Ilya (@iSazonov) please see Jason Shirk (@lzybkr)'s comment, which I totally agree. But we need to keep the existing fully qualified error ids, otherwise it would be a breaking change.

@daxian-dbw
Dongbo Wang (daxian-dbw) dismissed Bruce Payette (BrucePay)’s stale review April 20, 2017 22:30

The typo was fixed in new commits.

@iSazonov

Copy link
Copy Markdown
Collaborator Author

Thanks! I agree that this new message is more clear.

<value>The parameter requires at least `{0}` value(s) and no more than `{1}` value(s) - `{2}` value(s) were provided.</value>
</data>
<data name="ValidateCountEqualLengthFailure" xml:space="preserve">
<value>The parameter requires at least `{0}` value(s) and no more than `{1}` value(s) - `{2}` value(s) were provided.</value>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You don't need 3 resource strings, one would be enough since they are the same. The resource string name could be ValidateCountFailure.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I was very generous 😄
Fixed.


if (MinLength == MaxLength && len != MaxLength)
{
throw new ValidationMetadataException("ValidateCountEqualLengthFailure",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The error id ValidateCountEqualLengthFailure sounds confusing. Maybe ValidateCountNotExactlyEqual?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed.

<data name="ValidateCountMaxLengthFailure" xml:space="preserve">
<value>The number of provided arguments, ({1}), exceeds the maximum number of allowed arguments ({0}). Provide fewer than {0} arguments, and then try the command again.</value>
<data name="ValidateCountFailure" xml:space="preserve">
<value>The parameter requires at least `{0}` value(s) and no more than `{1}` value(s) - `{2}` value(s) were provided.</value>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We don't use backtick ` in error strings. I think you can just remove the backticks here.

@{ sb = { function Local:foo { param([ValidateCount(-1,2)] [string[]] $bar) }; foo }; FullyQualifiedErrorId = "ExceptionConstructingAttribute"; InnerErrorId = "" }
@{ sb = { function Local:foo { param([ValidateCount(1,-1)] [string[]] $bar) }; foo }; FullyQualifiedErrorId = "ExceptionConstructingAttribute"; InnerErrorId = "" }
@{ sb = { function Local:foo { param([ValidateCount(2, 1)] [string[]] $bar) }; foo }; FullyQualifiedErrorId = "ValidateRangeMaxLengthSmallerThanMinLength"; InnerErrorId = "" }
@{ sb = { function Local:foo { param([ValidateCount(2, 2)] [string[]] $bar) }; foo 1 }; FullyQualifiedErrorId = "ParameterArgumentValidationError,foo"; InnerErrorId = "ValidateCountEqualLengthFailure" }

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Error id has changed to ValidateCountNotExactlyEqual

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed.

@daxian-dbw

Copy link
Copy Markdown
Member

Add tests (blocked by #3456)

Ilya (@iSazonov) I'm merging this PR as it has corresponding tests. If you think more tests are needed for it, feel free to submit a new PR.
Like always, thank you for the great fixes!

@daxian-dbw
Dongbo Wang (daxian-dbw) merged commit e8ec400 into PowerShell:master Apr 22, 2017
@mklement0

Copy link
Copy Markdown
Contributor

It's great that you fixed this so quickly, but while the single error message is now technically accurate, I fear it doesn't provide the best guidance to the user.

As a user who has just mistakenly provided the wrong number of values x, I would want the error message to address my specific error, for a range a to z (simplified wording to illustrate the logic):

  • If a equals z: "You specified x, but you must specify exactly a."

  • Otherwise:

    • If x < a: "You specified x, but you must specify at least a (and no more than z)."

    • If x > z: "You specified x, but you must specify no more than z (but at least a)."

null, Metadata.ValidateCountNotInArray);
}

if (MinLength == MaxLength && len != MaxLength)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Isn't this case unnecessary now?

In fact, with one error message, there should be a single throw statement.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

We should to keep the two original fully qualified error ids to avoid a breaking change. But the new one I could to remove:

What is your conclusion about last Michael Klement (@mklement0) comment?
If you reject it I shall only remove the if (MinLength == MaxLength && len != MaxLength).
If you accept please give me right template.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The fully qualified error ids on parameter validation errors aren't too interesting, I'm not worried about changing those.

Personal opinion - adding prescriptive guidance may have been the cause for the original bug - having a confusing error message. It's easier to get technically accurate errors - what is wrong - than it is to suggest how to fix the problem, so it can be better to not bother. And in this specific case, I think it's fairly obvious how to fix the error.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Thanks! If Dongbo Wang (@daxian-dbw) and Michael Klement (@mklement0) do not object I'll create new PR tomorrow to only remove unneeded resource strings.

@mklement0 Michael Klement (mklement0) Apr 23, 2017

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Jason Shirk (@lzybkr)
I think the fundamental question is: Is it a design goal to provide prescriptive guidance? If it is (I think it should be), then let's fix and improve the currently broken / incomplete guidance - and that would mean fixing the 2 broken messages and adding one for the exact-count case.

There are limits to how helpful a generic validation error message can be (see #3630), but here's an opportunity to be as helpful as possible.

Personally, if I specified an incorrect number of values to a parameter that requires an exact number and I got the following message, I'd feel like I'm being presented with a brain-teaser rather than a helpful error message:
The parameter requires at least 2 value(s) and no more than 2 value(s).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Michael Klement (@mklement0) - you bring up two different issues - providing clear messages and providing prescriptive guidance.

In this case, one generic message is a bit weird, but felt like a corner case to me. After a quick search - ValidateCount isn't used that much (lots of duplicate hits from forks in the 426 results), but there are examples where Min==Max, so it's not as much of a corner case as I originally thought.

So I guess have 2 messages seems reasonable, but 3 still feels excessive.

My original thinking was - less and simpler code is ideal, and fewer error messages are also good (e.g. it reduces the translation efforts.)

As for prescriptive guidance, it's definitely not a goal for all error messages. To apply that standard widely, you'd end up with messages like Missing closing '}' in statement block or type definition, add the closing '}' and try again. And that feels unnecessary.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Jason Shirk (@lzybkr): You're right: "prescriptive" was not the right term (and I agree with not needing to go that far) - "specific to the error made" would have been better.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

What is a conclusion for new PR - leave one message and remove unneeded resource strings?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ilya (@iSazonov): Jason Shirk (@lzybkr) will have to confirm, but here's my understanding:

  • For the MinLength != MaxLength case: Use the just-added The parameter requires at least {0} value(s) and no more than {1} value(s) - {2} value(s) were provided. message.

  • For the MinLength == MaxLength case: add a new message along the lines of The parameter requires exactly {0} value(s) - {2} value(s) were provided.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants