Home > Mobile >  Should I rewrite my custom user-error handler using a native Python library?
Should I rewrite my custom user-error handler using a native Python library?

Time:07-04

I'm beginner-intermediate with Python/Django, and I'd like perspective on whether I should re-write my code to use either Python's native exception, warning or logging handlers.


My Python script parses through user submitted data, and looks for a lot of possible inconsistencies. These include:

  • Notices that are low urgency (e.g, we found duplicate rows)
  • Warnings that are problematic (e.g., rows we expected are missing)
  • Errors that require a re-upload (the data format is not valid)

After processing, I include all notices, warnings, and errors, along with a message for each one as part of a JSON object that saved with the Dataset. These are later parsed and rendered for the user user any time they view the DetailView for this object.

Currently I'm handling this through hand-written functions. For example:

from django.db import models


class Dataset(models.Model):

    notices = []
    warnings = []
    errors = []

    result = {}  # A models.JSONField() in the real code

    def process(self):

        rows = [
            {
                "title": "Row #1",
                "id": 123,
                "url": "/row/123"
             }
        ]

        for row in rows:
            if self._is_row_duplicate(row):
                self._notice_found_duplicate_row(row=row)

        self.result = {
            "errors": self.errors,
            "warnings": self.warnings,
            "notices": self.notices,
        }

        self.save()

    def _is_row_duplicate(self, row):
        # logic would go here
        return True

    def _notice_found_duplicate_row(self, row):
        title = f"Duplicate row: {row['title']}"
        message = f"There were multiple copies of this row: {row['id']}"
        url = row['url']
        data = {"title": title, "message": message, "url": url}

        if data not in self.notices:
            self.notices.append(data)

Dataset().process()

What I like about this:

  • I can trigger these messages with one line of code
  • The messages include a lot of rich information about the object
  • It won't include any duplicate messages

The problems I'm having are:

  • All of these functions are cluttering up my models.py (I have 24 already).
  • Functions outside this class can't append messages
  • I imagine that using a more "Pythonic" approach would be better for code legibility / maintainability

I'm trying to understand whether to use Python's exception, warning or logging tools, or something else entirely.

Exceptions

These seem designed for fatal code execution problems, which might be suitable only for my "errors" but nothing else.

Warnings

These are apparently intended to report warnings about potential code issues, not bad user data.

Logging

This seems designed to stream to a console or logging server, and capturing the output again seems to require a lot of boilerplate. In addition:

  • I'm not sure how to supress duplicate messages
  • I'd need to separate out these user-facing messages from any other log entries generated elsewhere in the code

Am I thinking about this the right way? Should I just leave this code alone? Maybe I just move all of my message functions to a mixin?

CodePudding user response:

If I understand correctly, you want to show these messages to users. In a web application: exceptions, logging and warnings are definitely not the right tools for this.

Exceptions and logging are generic concepts in programming, not specific to Python. You can learn further about those online.

Before I mention your solution, if you're using forms to get the 'user submitted data' you can look into django messages framework and maybe django form errors.

Your code seems to be syntactically wrong. Are you sure you posted the right code? If not, please update it.

Regarding the problems that you mentioned:

  • (As you said) you can generalize this behavior to a mixin, so you don't have to deal with repeated code.
  • Add an interface for the notices, warnings and errors, so that these can be accessed outside the class. For example methods like add_notice, add_warning, add_error.
  • Related