Not intuitive error message when value for property Format is not recognized
GregBalajewicz opened this issue · 10 comments
When a schema has an unexpected value for "format", it throw an unintuative error message. Perhaps a "unrecognized value of Int32 for format" would be better
TO REPRODUCE:
Schema:
{
"id": "greg1",
"$schema": "http://json-schema.org/draft-07/schema",
"title": "test3 api schema",
"type": "object",
"properties": {
"emplID": {
"type": "integer",
"format": "Int32",
"description": "Employee's ID"
}
},
"required": [ "emplID" ]
}
ERROR GENERATED :
NullReferenceException : Object reference not set to an instance of an object.
stack trace:
at Manatee.Json.Schema.FormatKeyword.Validate(SchemaValidationContext context)
at System.Linq.Enumerable.SelectIPartitionIterator2.ToList() at System.Linq.Enumerable.ToList[TSource](IEnumerable
1 source)
at Manatee.Json.Schema.JsonSchema.Validate(SchemaValidationContext context)
at Manatee.Json.Schema.PropertiesKeyword.Validate(SchemaValidationContext context)
at System.Linq.Enumerable.SelectIPartitionIterator2.ToList() at System.Linq.Enumerable.ToList[TSource](IEnumerable
1 source)
at Manatee.Json.Schema.JsonSchema.Validate(SchemaValidationContext context)
at Manatee.Json.Schema.JsonSchema.Validate(JsonValue json)
at Lcbo.Bimber.API.Utils.SchemaValidator2.Validate(String documentToValidate) in C:\Users\xtgab\Documents_projects\lcbo.bimber.api\Lcbo.Bimber.Api\Utils\SchemaValidator2.cs:line 76
This is a deserialization issue, not a validation issue, so validation error messages are moot here.
How are you deserializing the schema? There should be a check to validate the schema before deserializing it that doesn't seem to be happening.
Well, the json deserializes OK. it is a valid JSON. The issue is that validation does not recognize the value of the format field.
In fact, it seems to have problems with other format values. I ran into the same issue with:
"format": "date", in something like this :
"Status": {
"type": "object",
"properties": {
"Original_Hire_Date": {
"type": "string",
"format": "date",
},
"Start_Date": {
"type": "string",
"format": "date",
}
},
"required": [
"Original_Hire_Date"
]
},
Here is my code to deserialize the schema and do the validation:
var serializer = new JsonSerializer();
var json = JsonValue.Parse(schemaRaw);
var mySchema = serializer.Deserialize<Manatee.Json.Schema.JsonSchema>(json);
var val = JsonValue.Parse(documentToValidate);
SchemaValidationResults results = mySchema.Validate(val);
Where are you getting schemaRaw
?
The thing here is that the schema isn't being validated. If you're loading from a file, I suggest that you use JsonSchemaRegistry.Get()
and pass in the file name as a URI. This way the schema is validated. You'll find that Int32
and date
are not supported string format values (although date-time
is supported). If it's hard-coded, I suggest that you build the schema in code rather than as a string.
You can add support for new string formats by using one of the StringFormat
constructors. These will also register the new format for deserialization.
All that said, I did find a bug in that the system doesn't throw an exception when deserializing an unrecognized string format. I'll fix that.
@GregBalajewicz ping!
I'm putting an isKnownFormat
boolean in the AdditionalInfo
dictionary on the result object. That should indicate to you whether the format was recognized.
https://www.nuget.org/packages/Manatee.Json/
Version 10.0.5 contains your fix.
Sorry @gregsdennis! I was not able to get to this.
I've consumed your update and it works as expected, thanks! However, personally, I think the failure should occur when the schema is read in, and an unrecognized format is encountered. Right now, the schema is parsed, but failure occurs at validation time - format not recognized. IMO, the failure should occur during schema load in time, but this is not a big deal.
And to answer your question, my schema is coming from an external file. I cannot build it in code
JSON Schema specifies
If the type of the instance to validate is not in this set, validation for this format attribute and instance SHOULD succeed.
These means that I shouldn't throw exceptions when I don't recognize a format. Technically, I need to revisit what I did for this change. Unrecognized formats should succeed by default, and this change makes them fail by default.
I'll add in an option to indicate whether they should succeed or fail, though.
Additionally, the spec also says
Implementations MAY support the "format" keyword as a validation assertion. Should they choose to do so:
- they SHOULD implement validation for attributes defined below;
- they SHOULD offer an option to disable validation for this keyword.
@GregBalajewicz with v10.1.0 I've added an option that will trigger an exception when deserializing a schema with an unknown format.