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

refactor(api): more clear error messages for type validation when creating runtime parameters #14903

Merged
merged 4 commits into from
Apr 15, 2024

Conversation

jbleon95
Copy link
Contributor

@jbleon95 jbleon95 commented Apr 15, 2024

Overview

This PR closes a bunch of tickets related to unclear/confusing/incorrect error messages in failed analysis for RTP protocols.

The first set of fixes applies to AUTH-303, AUTH-305, AUTH-307 and AUTH-309, which all relate to string validation for variable_name, display_name (for both the parameter and choices) and unit. For these, we were not explicitly checking that the value given was a string, which could lead to related but unclear messages when those types inevitably would fail at some step on the process. Now, before we do any validation on string length, we ensure the value given is a string and raise an appropriate error message if it is not.

AUTH-304 related to an unclear message if the value key in a parameter choice was of the wrong type. This was a case of accidentally wrapping type around a type object, causing it to print <class 'type'> instead of <class 'str'> for example. This was a simple fix of just removing the type() call.

AUTH-306 was about unclear messages for the wrong type being used for minimum and maximum. The validation steps used for those was shifted around to more helpfully catch and point to incorrect types, rather than more generic error messages that didn't say which value was wrong.

Finally, AUTH-308 similarly brought up that there was no distinct error message when the default value was of the wrong type. To fix for this was just to make a bespoke check for that to raise a unique error message, rather than using the same check that setting the value uses. Its a small instance of repeated code but the check is simple enough and unlikely to be changed.

Test Plan

Ran through all the test protocols linked in the tickets above and ensured that they all had clear error messages relating to each individual one.

Changelog

  • Provide more clear error messages when non-string values are given to arguments that are string-only
  • Fix error message for wrong choice value not printing out the actual type that's expected
  • Refactored minimum/maximum validation to provide more clear error text to disambiguate which value is wrong.
  • Disambugate error message when default value is of the wrong type.

Review requests

Risk assessment

Low

@jbleon95 jbleon95 requested review from y3rsh, ecormany and sanni-t April 15, 2024 17:29
@jbleon95 jbleon95 requested a review from a team as a code owner April 15, 2024 17:29
Copy link
Contributor

@ecormany ecormany left a comment

Choose a reason for hiding this comment

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

Flagged a few possible edits and improvements. I didn't mark every single instance of each, so take whatever decisions you make and apply them to all the strings.

@@ -29,6 +29,10 @@ def validate_variable_name_unique(

def ensure_display_name(display_name: str) -> str:
"""Validate display name is within the character limit."""
if not isinstance(display_name, str):
raise ParameterNameError(
f"Display name must be a string and less than {DISPLAY_NAME_MAX_LEN} characters."
Copy link
Contributor

Choose a reason for hiding this comment

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

Probably at most rather than less than if the maximum is inclusive.

)
if len(unit) > UNIT_MAX_LEN:
raise ParameterNameError(
f"Description {unit} greater than {UNIT_MAX_LEN} characters."
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
f"Description {unit} greater than {UNIT_MAX_LEN} characters."
f"Unit {unit} greater than {UNIT_MAX_LEN} characters."

@@ -173,7 +189,7 @@ def _validate_choices(
ensure_display_name(display_name)
if not isinstance(value, parameter_type):
raise ParameterDefinitionError(
f"All choices provided must match type {type(parameter_type)}"
f"All choices provided must match type {parameter_type}"
Copy link
Contributor

Choose a reason for hiding this comment

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

match or be of (or something else) — what's most Pythonic, or most natural to protocol authors?

raise ParameterDefinitionError(
"Maximum must be greater than the minimum"
f"Minimum is type {type(minimum)}, must match parameter type {parameter_type}"
Copy link
Contributor

Choose a reason for hiding this comment

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

comma splice, easy to fix by adding a conjunction

Suggested change
f"Minimum is type {type(minimum)}, must match parameter type {parameter_type}"
f"Minimum is type {type(minimum)}, but must match parameter type {parameter_type}"

replace match here if changed above.

)
else:
raise ParameterDefinitionError(
"Only parameters of type float or int can have a minimum and maximum"
f"Parameter of type {parameter_type} does not support minimum or maximum arguments."
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the previous revision of this message was more informative. It says what does support min/max, not only that the current type doesn't. And I can't see a future type that isn't int or float supporting them, so no risk there.

validate_type(default, parameter_type)
if not isinstance(default, parameter_type):
raise ParameterValueError(
f"Parameter default {default} has type {type(default)}, must match type {parameter_type}."
Copy link
Contributor

Choose a reason for hiding this comment

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

apply two decisions from above:

  • is of type (or other term) instead of has type
  • add but to resolve comma splice

)
if len(description) > DESCRIPTION_MAX_LEN:
raise ParameterNameError(
f"Description {description} greater than {DESCRIPTION_MAX_LEN} characters."
Copy link
Contributor

Choose a reason for hiding this comment

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

Does {description} need to be enclosed in quotes so it doesn't run into the rest of the error text? It can be arbitrary text without punctuation, so it might be hard to read otherwise.

Copy link
Member

@sanni-t sanni-t left a comment

Choose a reason for hiding this comment

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

Minor stuff. Looks good otherwise!

@@ -173,7 +189,7 @@ def _validate_choices(
ensure_display_name(display_name)
if not isinstance(value, parameter_type):
raise ParameterDefinitionError(
f"All choices provided must match type {type(parameter_type)}"
f"All choices provided must match type {parameter_type}"
Copy link
Member

Choose a reason for hiding this comment

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

Maybe write it as f".. type '{parameter_type}'." (with quotes) to match the formatting of internal python type errors?

raise ParameterDefinitionError(
f"Minimum and maximum must match type {parameter_type}"
f"Maximum is type {type(minimum)}, must match parameter type {parameter_type}"
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
f"Maximum is type {type(minimum)}, must match parameter type {parameter_type}"
f"Maximum is type {type(maximum)}, must match parameter type {parameter_type}"

# These asserts are for the type checker and should never actually be asserted false
assert isinstance(minimum, (int, float))
assert isinstance(maximum, (int, float))
if maximum <= minimum:
Copy link
Member

Choose a reason for hiding this comment

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

Didn't notice this before and probably should check with @ecormany @y3rsh ..should we allow maximum == minimum?

Copy link
Member

@sanni-t sanni-t left a comment

Choose a reason for hiding this comment

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

Changes since last review LGTM!

@jbleon95 jbleon95 merged commit 55f798a into edge Apr 15, 2024
20 checks passed
@jbleon95 jbleon95 deleted the rtp_error_message_fixes branch April 15, 2024 21:15
Carlos-fernandez pushed a commit that referenced this pull request May 20, 2024
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.

3 participants