jsonix
jsonix copied to clipboard
Need async-style exception handling.
Really nice library, very comprehensive and it ate up some very complex schemas that I work with from an industry data consortium.
One thing that would be really nice is if the marshall/unmarshall code used the normal convention of calling the callback with function(err, document). In the current situation, it is impossible to catch any errors in the serialization or de-serialization process. Document validation errors are far too common to just have the program crash every time it encounters one. If I'm reading the code correctly, this could be a simple matter of putting the try/catch block in each of the marshal/unmarshal messages and calling the callback with either the parsed document or the errors.
What would be really sweet, but a bit more work, would be to continue parsing in the face of all but catastrophic errors, and then call the callback with both the object and an error list.
thanks again, ~Bill
Hi,
thanks for the feedback!
Would you please sketch a couple of API calls to demonstrate how you'd like it. I have my own ideas on that but it's helpful to have external opinion. Let's take the PO for example:
https://github.com/highsource/jsonix/blob/master/nodejs/tests/po/tests/po-tests.js
Could you please sketch the unmarshalling code how you'd imagine it?
Best wishes, Alexey
Essentially, I would like the callback signature to be fn(err, data){} as in all node js asynch functions.
unmarshaller.unmarshalFile( 'tests/po.xml',
function(err, poElement) {
if (err) {
// some error handling
return;
}
var po = poElement.value;
test.equal('Alice Smith', po.shipTo.name);
test.equal('123 Maple Street', po.shipTo.street);
test.equal('Mill Valley', po.shipTo.city);
test.equal('CA', po.shipTo.state);
test.equal('US', po.shipTo.country);
test.equal('Robert Smith', po.billTo.name);
test.equal('8 Oak Avenue', po.billTo.street);
test.equal('Old Town', po.billTo.city);
test.equal('PA', po.billTo.state);
test.equal('US', po.billTo.country);
test.done();
});
The implementation would be something like (very crudely, i have not tested code):
unmarshalFile : function(fileName, callback, options) {
if (typeof _jsonix_fs === 'undefined') {
callback(new Error("File unmarshalling is only available in environments which support file systems."));
}
// Need to catch any errors these might throw...
Jsonix.Util.Ensure.ensureString(fileName);
Jsonix.Util.Ensure.ensureFunction(callback);
if (Jsonix.Util.Type.exists(options)) {
Jsonix.Util.Ensure.ensureObject(options);
}
that = this;
var fs = _jsonix_fs;
fs.readFile(fileName, options, function(err, data) {
if (err) {
callback(err);
} else {
var text = data.toString();
var doc = Jsonix.DOM.parse(text);
try {
that.unmarshalDocument(doc);
callback(null, doc);
}
catch(e)
{
callback(e, null);
}
}
});
},
One other interesting approach for parsing errors would be to attach an error handler.
unmarshaller.on('error', callback);
unmarshaller.unmarshalXxx etc.
The return value of the callback could indicate whether to continue parsing. We find that often we have minor parsing errors that we wish to ignore. Sometimes, for instance, we can reach an unknown enumerated value, like a uom from a later version of the schema which is not strictly allowed but not important for our use of the document. This allows us to ignore the error, continue parsing the file and deal with the problem in some other way. This is perhaps a little trickier to implement because there are some errors that are so gross it is impossible to continue.
Thank you. The first point is quite easy to implement. The second is very close to my idea. I think, however, that more context info is needed to decide whether to fail or not. Type of error, path in the object structure, parent type, property. All these things. This is definitely doable, but requires careful design and certain effort. I'll split the issue. Thank you for your input.
Am 02.07.2015 um 03:21 schrieb William McKenzie [email protected]:
Essentially, I would like the callback signature to be fn(err, data){} as in all node js asynch functions.
unmarshaller.unmarshalFile( 'tests/po.xml', function(err, poElement) {
if (err) { // some error handling return; } var po = poElement.value; test.equal('Alice Smith', po.shipTo.name); test.equal('123 Maple Street', po.shipTo.street); test.equal('Mill Valley', po.shipTo.city); test.equal('CA', po.shipTo.state); test.equal('US', po.shipTo.country); test.equal('Robert Smith', po.billTo.name); test.equal('8 Oak Avenue', po.billTo.street); test.equal('Old Town', po.billTo.city); test.equal('PA', po.billTo.state); test.equal('US', po.billTo.country); test.done(); });The implementation would be something like (very crudely, i have not tested code):
unmarshalFile : function(fileName, callback, options) { if (typeof _jsonix_fs === 'undefined') { callback(new Error("File unmarshalling is only available in environments which support file systems.")); }
// Need to catch any errors these might throw... Jsonix.Util.Ensure.ensureString(fileName); Jsonix.Util.Ensure.ensureFunction(callback); if (Jsonix.Util.Type.exists(options)) { Jsonix.Util.Ensure.ensureObject(options); } that = this; var fs = _jsonix_fs; fs.readFile(fileName, options, function(err, data) { if (err) { callback(err); } else { var text = data.toString(); var doc = Jsonix.DOM.parse(text); try { that.unmarshalDocument(doc); callback(null, doc); } catch(e) { callback(e, null); } } }); },One other interesting approach for parsing errors would be to attach an error handler.
unmarshaller.on('error', callback); unmarshaller.unmarshalXxx etc. The return value of the callback could indicate whether to continue parsing. We find that often we have minor parsing errors that we wish to ignore. Sometimes, for instance, we can reach an unknown enumerated value, like a uom from a later version of the schema which is not strictly allowed but not important for our use of the document. This allows us to ignore the error, continue parsing the file and deal with the problem in some other way. This is perhaps a little trickier to implement because there are some errors that are so gross it is impossible to continue.
— Reply to this email directly or view it on GitHub.
Has there been any progress on this? Or is there any way currently to handle errors?
Edit: A workaround to this is to load the XML into a string using another method and then use the synchronous .unmarshalString(String) function surrounded by a try...catch to handle errors.
No, not yet, sorry.
I would also be interested in this feature. Good work so far!
This would be an awesome feature. Thanks for everything you've done so far.