Proposal: a new format for validation issues [Cerberus and Eve]

120 views
Skip to first unread message

Nicola Iarocci

unread,
Nov 19, 2013, 10:13:20 AM11/19/13
to pytho...@googlegroups.com
Hello folks,

I'm working on an experimental Cerberus branch that would change the way validation errors are reported in Cerberus and, consequently, by Eve. 

What we have right now is a list of errors. Each item in the list, while perfectly fine for human reading, isn't really ideal for algorithm parsing. Why would you want to parse the errors with an algorithm? A common case would be when your client is using business objects to represent API resources (think a client-side ORM), and would have a hard time binding validation errors to the objects themselves.

What I am experimenting with is converting the issues list to a dict in which fields would be dict keys, and errors the values. So for example, instead of:

>>> validator.errors
["min value for field 'age' is 10", "value of field 'name' must be of string type"]

you would have:

>>> validator.errors
{'age': 'min value is 10', 'name': 'must be of string type'}

This system would also allow for future expansion, like providing a unique code for every error type, etc.

Overall I'm fairly confident that this would be an important step forward, however I am unsure on how to handle fields of list types. Suppose you have a a list field with a schema like this:

            'a_list_of_values': {
                'type': 'list',
                'items': [{'type': 'string'}, {'type': 'integer'}, ]
            },

And your document is like this:

'a_list_of_values': ['a string', 'not an integer']

Given the new dictionary format, how would you report the error on the second field?

>>> validator.errors
{'a_list_of_values[1]': 'must be of integer type'}

Or:

>>> validator.errors
{'a_list_of_values': (1,'must be of integer type')}

Let's see what would happen in case of multiple validation errors within the same list:

>>> validator.errors
{'a_list_of_values[0]': 'must be of string type'}
{'a_list_of_values[1]': 'must be of integer type'}

Alternatively:

>>> validator.errors
{'a_list_of_values': [(1,'must be of integer type'), (0, 'must be of string type')]}

I tend to prefer the second option, in which we have a tuple with the list index and the error. This would make parsing much easier (no need to parse the keys, and you have only one key per field), at the cost of reduced user readability.

Again I'm convinced that, while it would sort of break backward compatibility, in the long run the new dict format would help client SDK developers immensely. Nothing is set on stone though, and I am particularly curious on what is your take on the lists format. Any feedback greatly appreciated,

Cheers,
Nicola.

Nicola Iarocci

unread,
Nov 28, 2013, 10:30:24 AM11/28/13
to pytho...@googlegroups.com
Status update:

In the prototype I'm working on right now I went for dicts instead of tuples. So, in a list of dicts like this:

{'rows': [{'sku': 1, 'price': '100'}, {'sku':'ciao', 'price':'1'}]}

errors would be reported like this:

{'rows': {0: {'sku': 'must be of string type', 'price': 'must be of integer type'}, 1: {'price': 'must be of integer type'}}}

By contrasts, on top of my memory, the current Cerberus release would report:

['"rows[0]": field "sku" in must be of string type', '"rows[0]" field "price" in must be of integer type', '"rows[1]" field "price" in must be of integer type']

Notice how, in the current implementation, a client would be forced to parse the list in order to retrieve the line number, the offending field, and the error.

- Nicola

Nicola Iarocci

unread,
Nov 28, 2013, 10:37:59 AM11/28/13
to pytho...@googlegroups.com
Just to clarify, this is *not* coming with Eve 0.2 (next release). Most likely will get merged into 0.3 (of course with a new Cerberus release).

Nicola

Nicola Iarocci

unread,
Dec 4, 2013, 5:46:53 AM12/4/13
to pytho...@googlegroups.com
Alright folks,

I released Cerberus 0.5 with support for the new validation errors format. Eve-dev has also received a patch to support the new format (Cerberus 0.5 is now required). Again, this is currently on the development branch. Will be released with 0.3.

Cheers,
N.
Reply all
Reply to author
Forward
0 new messages