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 error handling in CustomDjangoCache #11808

Conversation

thesujai
Copy link
Contributor

@thesujai thesujai commented Jan 26, 2024

Summary

The new approach consolidates handling of sqlite3.OperationalError and
AssertionError across multiple cache methods, also it makes the
internal implementation more cleaner without breaking anything

References

Fixes #11767

Reviewer guidance

Confused about the naming, so i gave functions descriptive names

please take your time to review it, no rush


Testing checklist

  • Contributor has fully tested the PR manually
  • If there are any front-end changes, before/after screenshots are included
  • Critical user journeys are covered by Gherkin stories
  • Critical and brittle code paths are covered by unit tests

PR process

  • PR has the correct target branch and milestone
  • PR has 'needs review' or 'work-in-progress' label
  • If PR is ready for review, a reviewer has been added. (Don't use 'Assignees')
  • If this is an important user-facing change, PR or related issue has a 'changelog' label
  • If this includes an internal dependency change, a link to the diff is provided

Reviewer checklist

  • Automated test coverage is satisfactory
  • PR is fully functional
  • PR has been tested for accessibility regressions
  • External dependency files were updated if necessary (yarn and pip)
  • Documentation is updated
  • Contributor is in AUTHORS.md

@github-actions github-actions bot added DEV: backend Python, databases, networking, filesystem... SIZE: medium labels Jan 26, 2024
@thesujai
Copy link
Contributor Author

thesujai commented Jan 26, 2024

py 2.7 tests are failing because 0-args super() is supported from py 3.0
Maybe re-targetting to develop may work
or if that conflicts with the milestones, let me know so I can make change here to support py2.7 :)

@rtibbles rtibbles assigned akolson and unassigned akolson Jan 27, 2024
Copy link
Member

@rtibbles rtibbles left a comment

Choose a reason for hiding this comment

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

We do indeed want this to be Python 2.7 compatible, and most of the instances you have written are.

I have suggested a way to DRY this up slightly, which will also solve this, but you could equally just not call super in that way in the couple of instances you have.

@@ -13,6 +13,32 @@ class CustomDjangoCache(DjangoCache):
https://github.com/grantjenks/python-diskcache/blob/v4.1.0/diskcache/djangocache.py
"""

ERRORS_TO_HANDLE = (sqlite3.OperationalError, AssertionError)

def try_execute_return_none_on_error(self, method, *args, **kwargs):
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 you could simplify this all somewhat by having a single method like this:

def try_execute(self, method_name, error_return_value, *args, **kwargs):
    try:
        method = getattr(super(CustomDjangoCache, self), method_name)
        if method is None:
            raise ValueError("{method_name} is not a valid method".format(method_name=method_name))
        return method(*args, **kwargs)
    except self.ERRORS_TO_HANDLE:
        return error_return_value

That way you can guarantee you're using the Py2.7 compatible form of super, and you don't need to define 4 different functions that are doing the same thing.

If a function doesn't return a value explicitly in Python, it returns None, so you can pass None as the error_return_value in those cases.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the code snippet, indeed this thought crossed my mind, but i was confused about error_return_value having types. Now it makes more sense to me

@thesujai
Copy link
Contributor Author

I've incorporated the suggested changes, let me know for additional adjustments or improvements at your convenience

except sqlite3.OperationalError:
return False
return self.try_execute(
method_name="add",
Copy link
Member

@rtibbles rtibbles Jan 31, 2024

Choose a reason for hiding this comment

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

Sorry, just one more thing - I think this probably does work to pass positional arguments as named keyword arguments, but I would find it less confusing if method_name and error_return_value were passed just as positional arguments in each instance here, so:

return self.try_execute(
    "add",
    False,

And so on.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

sure, sorry for the trouble

Copy link
Member

@rtibbles rtibbles left a comment

Choose a reason for hiding this comment

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

This is great, thanks @thesujai. I will hold off on final approval here, as we are only merging critical bug fixes right now into release-v0.16.x in anticipation of our 0.16.0 release.

We will merge once that release has been finalized!

@rtibbles rtibbles added this to the Kolibri 0.16: Planned Patch 1 milestone Feb 1, 2024
@rtibbles rtibbles self-assigned this Feb 13, 2024
@rtibbles rtibbles merged commit 017af53 into learningequality:release-v0.16.x Feb 23, 2024
34 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
DEV: backend Python, databases, networking, filesystem... SIZE: medium
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants