Closed reecemillsom closed 8 years ago
This error originates from here:
Resource.prototype.sync = Promise.denodeify(function(callback) {
var self = this;
var target = self._client._update;
if (!self._getBase().id) {
target = self._client._remoteCreate;
}
target.call(self._client, self, function(err, rawResponse, rawResource) {
if (err) return callback(err);
self._construct(rawResource, self._client);
The job of Resource.sync
is to either update the resource, or create it if it doesn't exist. Following an update, the remote response should contain the newly modified resource, which we use to synchronise the local Resource.
I'd be interested to know how we're getting no error in combination with a null data
payload. I think the only course of action if this scenario is to throw an Error - I'm pretty sure this behaviour isn't allowed in the specification?
The following DEBUG output should help to clarify the sequence of events (this was obtained by tweaking the people
resource definition in the jsonapi-server
examples with the above mentioned changes):
jsonApi:requestCounter 0 +0ms POST /rest/people
jsonApi:validation:input {"id":"79c7eee6-0078-472e-b5c7-08d13b92b8ca","type":"people","email":"john.doe@example.com"} +3ms
jsonApi:handler:create {"type":"people","data":{"id":null,"type":"people","attributes":{"email":"john.doe@example.com"},"relationships":{}}} +1ms [null,{"id":"79c7eee6-0078-472e-b5c7-08d13b92b8ca","type":"people","email":"john.doe@example.com"}]
jsonApi:handler:find {"type":"people","data":{"id":null,"type":"people","attributes":{"email":"john.doe@example.com"},"relationships":{}},"id":"79c7eee6-0078-472e-b5c7-08d13b92b8ca"} +0ms [null,{"id":"79c7eee6-0078-472e-b5c7-08d13b92b8ca","type":"people","email":"john.doe@example.com"}]
jsonApi:validation:output {"id":"79c7eee6-0078-472e-b5c7-08d13b92b8ca","type":"people","email":"john.doe@example.com"} +1ms
jsonApi:requestCounter 1 +9ms GET /rest/people/79c7eee6-0078-472e-b5c7-08d13b92b8ca
jsonApi:handler:find {"type":"people","id":"79c7eee6-0078-472e-b5c7-08d13b92b8ca"} +1ms [null,{"id":"79c7eee6-0078-472e-b5c7-08d13b92b8ca","type":"people","email":"john.doe@example.com"}]
jsonApi:validation:output {"id":"79c7eee6-0078-472e-b5c7-08d13b92b8ca","type":"people","email":"john.doe@example.com"} +0ms
jsonApi:requestCounter 2 +5ms POST /rest/people
jsonApi:validation:input {"id":"be2d1e75-28a2-4895-aa0a-653d3d803f98","type":"people"} +1ms
jsonApi:handler:create {"type":"people","data":{"id":null,"type":"people","attributes":{},"relationships":{}}} +0ms [null,{"id":"be2d1e75-28a2-4895-aa0a-653d3d803f98","type":"people","email":""}]
jsonApi:handler:find {"type":"people","data":{"id":null,"type":"people","attributes":{},"relationships":{}},"id":"be2d1e75-28a2-4895-aa0a-653d3d803f98"} +0ms [null,{"id":"be2d1e75-28a2-4895-aa0a-653d3d803f98","type":"people","email":""}]
jsonApi:validation:output {"id":"be2d1e75-28a2-4895-aa0a-653d3d803f98","type":"people","email":""} +0ms
jsonApi:validation:error child "email" fails because ["email" is not allowed to be empty] +1ms {"id":"be2d1e75-28a2-4895-aa0a-653d3d803f98","type":"people","email":""}
Ok. In this instance, the Joi schema is invalid. a ""
value is not accepted by the Joi.string()
validator.
> var t = Joi.string().allow(null).default("");
undefined
> Joi.validate("test", t, function() { console.log(arguments) });
{ '0': null, '1': 'test' }
undefined
> Joi.validate(undefined, t, function() { console.log(arguments) });
{ '0': null, '1': '' }
undefined
> Joi.validate('', t, function() { console.log(arguments) });
{ '0':
{ [ValidationError: "value" is not allowed to be empty]
name: 'ValidationError',
details: [ [Object] ],
_object: '',
annotate: [Function] },
'1': '' }
"test"
validates fine.undefined
get changed to the default of ""
""
is an invalid value.The default you've chosen doesn't match your validation :(
I have encountered this type of error. It crashed my client when I try to sync the resource with ' '. How to fix this?
How to reproduce To reproduce in any resource have a default of an empty string on a property as well as an allow key with null.
This is an example:
If you create the resource when sync is executed it crashes with the following partial stack trace: