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

Notifications: small fixes found after reviewer #10996

Merged
merged 9 commits into from
Jan 8, 2024

Conversation

humitos
Copy link
Member

@humitos humitos commented Jan 4, 2024

Related to #10922 (comment).

Screenshot_2024-01-04_16-30-05

Use single `{}` since we are using `.format()` to format these strings.
Avoid internal error and log the exception so we can figure it out how to solve
it. This happens when the `Notification` does not have _all_ the required `format_values`.
@humitos humitos requested a review from stsewd January 4, 2024 15:24
@humitos humitos requested a review from a team as a code owner January 4, 2024 15:24
readthedocs/notifications/messages.py Outdated Show resolved Hide resolved
except KeyError:
# There was a key missing
log.exception("There was a missing key when formating a header's Message.")
return self.header.format_map(defaultdict(str, **self.format_values))
Copy link
Member

Choose a reason for hiding this comment

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

Since we have control over the notification, I think this should fail hard, our tests should catch these instead of silently failing.

Copy link
Member Author

Choose a reason for hiding this comment

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

We can't catch this by tests since this rendering happens at runtime. This could happen because a Notification was created with invalid format values, or because we have change the message over time and started required more format values.

Copy link
Member

Choose a reason for hiding this comment

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

The idea here would be to test for each notification we generate on each part of the code base. If we generate a notification when the user does something, we should have a test for it.

Copy link
Member Author

Choose a reason for hiding this comment

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

That's fine, we can test the current state, but it could fail still in the future:

  1. we have a notification with body="Go to {url} and put {code}." and format_values={"url": "https://..", "code": 1234}
  2. in the future, we change the message to body="Go to {url} and put {code}. Otherwise, contact support at {email}

At this point, all the old notifications with only url and code as format values will start to fail because they are missing the email key. This check here is to protect ourselves against this issue.

Copy link
Member Author

Choose a reason for hiding this comment

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

We will find some edge cases as we go that we can improve and write test cases for them and protections like this one against them.

We don't support nested dictionaries in `format_values` or random objects.
Only `str` and `int`. That should be enough for now.

Skip all the values that are not `str` or `int` from the format values to render
the messages.
@humitos humitos requested a review from stsewd January 4, 2024 18:17
@humitos
Copy link
Member Author

humitos commented Jan 8, 2024

@stsewd I'd like to get an approve here so we can deploy this tomorrow. Can you take a final look at it? 🙏🏼

return {
key: escape(value)
for key, value in format_values.items()
if isinstance(value, (str, int))
Copy link
Member

Choose a reason for hiding this comment

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

I think this is fine without this check, there are more built-in types that can be included (like bool).

Suggested change
if isinstance(value, (str, int))

We should have more tests instead.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, we can expand to other types in the future. I want to avoid running escape(dict) and returning 500. For now, str and int are the ones we are using.

except KeyError:
# There was a key missing
log.exception("There was a missing key when formating a header's Message.")
return self.header.format_map(defaultdict(str, **self.format_values))
Copy link
Member

Choose a reason for hiding this comment

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

The idea here would be to test for each notification we generate on each part of the code base. If we generate a notification when the user does something, we should have a test for it.

@humitos humitos merged commit a2dde87 into main Jan 8, 2024
7 checks passed
@humitos humitos deleted the humitos/notifications-fixes branch January 8, 2024 17:03
Copy link

sentry-io bot commented Jan 9, 2024

Suspect Issues

This pull request was deployed and Sentry observed the following issues:

  • ‼️ AttributeError: 'str' object has no attribute 'name' /projects/{project_slug}/builds/{build_pk}/ View Issue
  • ‼️ KeyError: 'instance' /projects/{project_slug}/builds/{build_pk}/ View Issue

Did you find this useful? React with a 👍 or 👎

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

2 participants