Report an error during validation.

        There are two error messages. The legacy message is used for backwards
        compatibility and usually contains the object (possibly very large)
        that failed to validate. The new message is much better as it contains
        just a short message on what went wrong. User code can inspect
        object_expr and schema_expr to see which part of the object failed to
        validate against which part of the schema.

        The schema_suffix, if provided, is appended to the schema_expr.  This
        is quite handy to specify the bit that the validator looked at (such as
        the type or optional flag, etc). object_suffix serves the same purpose
        but is used for object expressions instead.

def _report_error(self, legacy_message, new_message=None,
                      schema_suffix=None):
        """
        Report an error during validation.

        There are two error messages. The legacy message is used for backwards
        compatibility and usually contains the object (possibly very large)
        that failed to validate. The new message is much better as it contains
        just a short message on what went wrong. User code can inspect
        object_expr and schema_expr to see which part of the object failed to
        validate against which part of the schema.

        The schema_suffix, if provided, is appended to the schema_expr.  This
        is quite handy to specify the bit that the validator looked at (such as
        the type or optional flag, etc). object_suffix serves the same purpose
        but is used for object expressions instead.
        """
        object_expr = self._get_object_expression()
        schema_expr = self._get_schema_expression()
        if schema_suffix:
            schema_expr += schema_suffix
        raise ValidationError(legacy_message, new_message, object_expr,
                              schema_expr)