everit-org / json-schema

JSON Schema validator for java, based on the org.json API
Apache License 2.0
866 stars 282 forks source link

Empty message for 'const' schema validation #316

Open omklymenko opened 5 years ago

omklymenko commented 5 years ago

Steps: provide param001 that is not correct according to 'const' constraint (not equal to const) "param001": { "title": "integer", "default": 1, "type": "integer", "const": 500 } Actual result: "#/parentProperty/smth/param001: " Expected result: some valuable message (for example, 'provided value is not equal to 500')

Is there any workaround? Thanks a lot:)

erosb commented 5 years ago

Hi! I will think about some way to provide a workaround. My concern here is that the expected "const" value is not necessarily a primitive value, it can also be a huge object or array. Therefore I don't want to include neither the expected nor the actual value (at least by default), because it can lead to obscure performance problems under extreme circumstances.

For now I suggest being conservative looking up the expected value using ValidationException#getSchemaLocation() and JSONObject#query() if that works.

omklymenko commented 5 years ago

Thanks a lot! By the way, ValidationException#getErrorMessage() is empty for 'const' and doesn't contain actual value for 'exclusiveMaximum' (#somePath/property: is not less than 7)

CoCumis commented 5 years ago

Could we have this implemented at least for string types? Assume this model (maybe a little bit overkill for explanation of this issue):

{
    "type": "object",
    "properties":{
        "prop": {
            "$ref": "#/definitions/PropEnum"
        }
    },
    "oneOf": [{
        "properties": {
            "prop": {
                "const": "A"
            },
            "a": {
                "type": "string"
            }
        },
        "required": ["a"]
    }, {
        "properties": {
            "prop": {
                "const": "B"
            },
            "b": {
                "type": "string"
            }
        },
        "required": ["b"]
    }],

    "definitions": {
        "PropEnum": {
            "type": "string",
            "enum": ["A", "B"]
        }
    }

}

When you will provide some invalid value in prop field, let's say "C", the validation result will be empty: #/prop: The workaround is to use enum like this:

    "oneOf": [{
        "properties": {
            "prop": {
                "enum": ["A"]
            },
            "a": {
                "type": "string"
            }
        },
        "required": ["a"]
    }, {
        "properties": {
            "prop": {
                "enum": ["B"]
            },
            "b": {
                "type": "string"
            }
        },
        "required": ["b"]
    }],

Then I see correct validation error: #/prop: C is not a valid enum value

mmorel-35 commented 4 years ago

Instead of

 failureReporter.failure("", "const");

What to you think of limiting the length of the printed subject if the length is the problem ?

failureReporter.failure(format("%.1024s is not the valid value", subject), "const");

I'm using 1024 as an example off course

erosb commented 4 years ago

Hello, I think it makes more sense to include a reference to the violating instance in all ValidationExceptions (eg. ValidationException#getViolatingInstance(), as a more generic approach. It still wouldn't be included in the exception message, but it would be simple to access. What do you think?

mmorel-35 commented 4 years ago

I'm using the ValidationException#getAllMessages() to print to submitters of json objects the result of the validation against a schema Would your idea help those, having a better understanding of what is wrong in what they submitted ? If I take @CoCumis 's example, they know where is located the problem but they have no clue of what is wrong until they understand the schema