Created
January 11, 2014 02:09
-
-
Save mikermcneil/8366092 to your computer and use it in GitHub Desktop.
hack to determine whether an error is a validation error from waterline (for Sails/Waterline 0.9.x)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} |
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)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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