-
-
Save mikermcneil/8366092 to your computer and use it in GitHub Desktop.
var _ = require('lodash'); | |
/** | |
* `isValidationError` | |
* | |
* Is this a waterline validation error? | |
*/ | |
function isWaterlineValidationError (err) { | |
if (_.isPlainObject(err)) { | |
var keys = Object.keys(err); | |
if (keys.length) { | |
var failedValidation = err[keys[0]]; | |
if (_.isArray(failedValidation) && failedValidation.length && | |
_.isPlainObject(failedValidation[0]) && failedValidation[0]['rule'] | |
) { | |
return true; | |
} | |
} | |
} | |
if ( _.isString(err) && err.match(/duplicate key value violates unique constraint/g) ) { | |
return true; | |
} | |
if ( _.isString(err) && err.match(/^Bad request/ig)) { | |
return true; | |
} | |
return false; | |
} |
Also
/**
* Takes a Sails Model object (e.g. User) and a ValidationError object and translates it into a friendly
* object for sending via JSON to client-side frameworks.
*
* To use add a new object on your model describing what validation errors should be translated:
*
* module.exports = {
* attributes: {
* name: {
* type: 'string',
* required: true
* }
* },
*
* validation_messages: {
* name: {
* required: 'you have to specify a name or else'
* }
* }
* };
*
* Then in your controller you could write something like this:
*
* var validator = require('sails-validator-tool');
*
* Mymodel.create(options).done(function(error, mymodel) {
* if(error) {
* if(error.ValidationError) {
* error_object = validator(Mymodel, error.Validation);
* res.send({result: false, errors: error_object});
* }
* }
* });
*
* @param model {Object} An instance of a Sails.JS model object.
* @param validationErrors {Object} A standard Sails.JS validation object.
*
* @returns {Object} An object with friendly validation error conversions.
*/
module.exports = function(model, validationError) {
var validation_response = {};
var messages = model.validation_messages;
validation_fields = Object.keys(messages);
validation_fields.forEach(function(validation_field) {
if(validationError[validation_field]) {
var processField = validationError[validation_field];
//console.log(processField);
processField.forEach(function(rule) {
if(messages[validation_field][rule.rule]) {
if(!(validation_response[validation_field] instanceof Array)) {
validation_response[validation_field] = new Array();
}
var newMessage={};
newMessage[rule.rule] = messages[validation_field][rule.rule];
validation_response[validation_field].push(newMessage);
}
});
}
});
return validation_response;
};
Thanks. This code on the last comment is great.
It makes it easier to translate error messages with i18n also.
@afonsomota np! It's actually not mine, so I can't take the credit. Someone shared it in IRC-- wish I could remember who... :\
I think its _sfb. Anyway, I'm also using that solution to provide custom validation messages, but the problem is if you didn't provide a custom validation message to some fields, only the fields where you provided a custom validation message will have error messages :/
Anyone have other solutions or improvements on the current solution above?
I hope custom validation messages will really be supported really soon - balderdashy/sails#1173
Here's my version of the code above to generate generic error message if no custom message defined.
/**
* Takes a Sails Model object (e.g. User) and a ValidationError object and translates it into a friendly
* object for sending via JSON to client-side frameworks.
*
* To use add a new object on your model describing what validation errors should be translated:
*
* module.exports = {
* attributes: {
* name: {
* type: 'string',
* required: true
* }
* },
*
* validation_messages: {
* name: {
* required: 'you have to specify a name or else'
* }
* }
* };
*
* Then in your controller you could write something like this:
*
* var validator = require('sails-validator-tool');
*
* Mymodel.create(options).done(function(error, mymodel) {
* if(error) {
* error_object = validator(Mymodel, error);
* res.send({result: false, errors: error_object});
* }
* });
*
* @param model {Object} An instance of a Sails.JS model object.
* @param validationErrors {Object} A standard Sails.JS validation object.
*
* @returns {Object} An object error messages in array.
* NOTE:
* ARRANGEMENT OF ERROR MESSAGES WILL FOLLOW HOW YOU DEFINE YOUR FIELD
*/
module.exports = function(model, err){
if(!err.ValidationError) return
var validationError = err.ValidationError;
var custom_messages = model.validation_messages;
var error_fields = Object.keys(validationError);
var error_messages = {};
error_fields.forEach(function(field){
error_messages[field] = new Array();
field_messages = custom_messages[field]
validationError[field].forEach(function(err){
if(!field_messages) error_messages[field].push(field + " should be " + err.rule);
else{
error_message = field_messages[err.rule]? field_messages[err.rule] : (field + " should be " + err.rule);
error_messages[field].push(error_message)
}
});
});
return error_messages;
}
@danegigi @basco-johnkevin @afonsomota Hey y'all- check out the latest version of Sails/Waterline on master branch on github. Waterline errors have been normalized into a more predictable format. Still needs some work/testing, but the situation is much better now.
@mikermcneil Is okay to just check e.code
? as on master
if (e.code && e.code === 'E_VALIDATION') {
// var validationErrors = e.invalidAttributes;
}
For sails v0.11.X you may use this sails-hook-validation
More compact solution
function(err, model) {
// no errors
if (!err) return true;
// error is not a validation error
if (!err.ValidationError) return false;
// { field: { rule: 'Message', otherRule: 'Message' ... } ... }
var messages = model.validationMessages,
errors = err.ValidationError,
output = {};
Object.keys(errors).forEach(function(field) {
output[field] = [];
errors[field].forEach(function(error) {
output[field].push(messages[field] && messages[field][error.rule] || error.rule);
})
});
return output;
}
Note that in Sails v1 this is changing a bit. For details, see the docs on sailsjs.com (or balderdashy/sails#3459 (comment) for a bit more background)
http://hastebin.com/misewipafa.js