Thursday, March 1, 2012

Using a dictionary to populate a format string in python for human and computer-friendly error reporting

Python 2.6 has brought some interesting string formatting options to the table. I recently needed an object that could pass back error information that could be consumed by humans and other code. The new string formatting came in handy.

class ValidationError(Exception):
  """Class for reporting validation errors."""

  BAD_RECORD = 1

  def __init__(self, error, msg, **kwargs):
    """Record Validation Error.

    Requires python 2.6

    Args:
      error: ValidationError code e.g. ValidationError.BAD_RECORD
      msg: format string for human readable version of the error
      **kwargs: kwargs to populate format string
    """
    super(ValidationError, self).__init__(self)
    self.message = msg.format(**kwargs)
    self.error = error
    self.kwargs = dict(kwargs)

  def __str__(self):
    return self.message

You can use it like this:

e = ValidationError(ValidationError.BAD_RECORD,
                    'Bad record detected in {records}',
                    records=records)

So to present the info to a human:
In [18]: print e
Bad record detected in {'a': 12, 'b': 123}
and other code can use:
In [19]: e.error
Out[19]: 1
and access the relevant varaibles like:
In [20]: e.kwargs
Out[20]: {'records': {'a': 12, 'b': 123}}

No comments: