Send parameter with intercept in SailsJS - sails.js

throw { badCombo: 'Invalid email or username.' }
.intercept('incorrect', 'badCombo')
Hi,
How can I send the parameter with intercept, as with throw?

.intercept()
will accept two parameters
.intercept(filter, handler)
or just the handler
.intercept(handler)
to intercept all errors.
Handler here is the function which can either throw or simply use res object to respond with the error.
So one option to achieve desired result will be:
.intercept('incorrect', () => res.serverError({ badCombo: 'Invalid email or username.' });
Replace serverError with badRequest depending on your intent.
Another option would be to simply throw your error in the handler:
.intercept('incorrect', () => {
throw { badCombo: 'Invalid email or username.' };
};

Related

How to handle non explicit errors inside sails.js helpers?

I am trying to figure out how the Error handling in Sails.js works. Unfortunatley the code examples in the docs do not cover this use case.
The problem is I keep getting this error:
UsageError: `.intercept()` handler returned `undefined`, but this should never happen.
Regardless, here is a summary of the original underlying error:
Now all I am trying to do is call a helper and if it fails, then I want to catch the error (any), log it and run some code. If I wouldn't be using Sails but normal promises I would have handled it like this:
await helper().catch((err) => { // run some code }
In Sails I should be able to use .intercept() instead of .catch()
My code looks like this:
// ExportController.js
const csv = await sails.helpers.files.convertToCsv(data)
.intercept((err) => {
sails.log.error(err)
req.addFlash('error_messages', 'Error parsing data to csv!')
return res.redirect(`/`);
})
// convert-to-csv.js
if (!Array.isArray(inputs.data)) {
throw new Error('invalid inputs.data type: ' + typeof inputs.data)
};
Now how can I avoid getting this error?
The code examples show only cases where errors that are explicitly added to the exits object are handled, but not for general error handling.
In the docs it says that if the filter argument is
not provided, ALL errors will be intercepted.
Or is that only true for db queries? Because the .intercept() doc section is in that subcategory.
You could use “throw ‘errorCode’;” for example:
Set the exits:
exits {
errorWithCsvFile: {
responseType: 'badRequest'
}
}
const csv = await sails.helpers.files.convertToCsv(data)
.intercept(‘somethingWrongCode’, ‘errorWithCsvFile’)
... // Other handles
.intercept(err => new Error(err))
Alternative:
try {
...
const csv = await sails.helpers.files.convertToCsv(data)
.intercept((err) => {
sails.log.error(err)
req.addFlash('error_messages', 'Error parsing data to csv!')
throw 'badRequest';
})
...
} catch (err) {
sails.log.err(err);
return res.redirect(`/`);
}

Protractor- automate the error message on tab out when input field is empty

I have an angular2 application where I am trying to write end to end test cases to automate things.I have just begun with learning Protractor for this and trying to implement a negative test case for a form field where if any field is empty, the error message should be shown. I have tried something like below to automate the form and its working fine.
In my spec.ts-
import userDetailsPage from './userDetails.e2e-po;
it('should fill out User Details', () => {
const userDetail: IUserDetail = {
firstName: 'Lorem',
lastName: 'Ipsum'
};
userDetailsPage.populateUserDetails(userDetail);
});
In userDetails.e2e-po-
populateUserDetails(details: IUserDetail) {
this.fillFirstName(details.firstName)
.fillLastName(details.lastName)
return this;
}
I am writing the below code which automatically inputs the firstName and lastName field.
fillLastName(last: string) {
let el = element(by.css('input[name="lastName'));
el.clear().then(() => {
el.sendKeys(last);
});
return this;
}
The above scenario works fine. But I am also trying to achieve a scenario where I do not input either first name or last name field, should throw me an error message.Can someone let me know what else should I add to achieve this.
I am already handling the validation in my HTML.
Any help is much appreciated.
Instead of details.firstname and details.lastname put empty strings and then validate the error that occurs on the page.
I think you can try the following method as a reusable function
function formValidate(donefn){
newProjBtn.click().then(async function () {
var lastName_fld = element(by.css('input[name="lastName'));
await lastName_fld.sendKeys("", protractor.Key.TAB);
//browser.sleep(2000);
var elm = element(by.css(".error-message"));
elm.isPresent().then(function(result){
if(result){
console.log("Error message displayed")
//some more code to do like selecting the field and enter the test
return result;
}else{
console.log("Error message not displayed")
return result;
}
})
donefn();
})
I solved it in this way:
await input.sendKeys(protractor.Key.CONTROL, 'a');
await input.sendKeys(protractor.Key.BACK_SPACE);
await input.sendKeys(protractor.Key.TAB);
//then the error-message will appear

Angular2 return data from validation service after Http call

I have build a validation service for my registration form and one of the static methods is checking if the entered email is available by calling my API the following:
static emailAvailable(control){
let injector = ReflectiveInjector.resolveAndCreate([HTTP_PROVIDERS]);
let http = injector.get(Http);
let valid = "E-mail is available";
http.post('https://secretapi.com/email', JSON.stringify({ email: control.value }))
.map((res: Response) => res.json())
.subscribe(function(result){
if(result.success){
valid = result.success; //The console.log on the line below is correct, the one at the bottom of the script never changes.
console.log(valid);
return null; //Doesn't do anything?
}else{
valid = result.error; //The console.log on the line below is correct, the one at the bottom of the script never changes.
console.log(valid);
return { 'invalidEmailAddress': true }; //Doesn't do anything, just like the return above
}
});
console.log(valid); //Output always "E-mail is available"
}
It should return "null" to the form validator when the email is available. The last console.log at the bottom should output the message that it recieves in the subscribe call. This doesn't happen and I'm not sure why. For some reason everything that happens within the subscribe call is contained there and never reaches the validator. What should I change? I have no idea and been searching the web for hours now.
You have to return Observable or Promise from your validator:
return http.post('https://secretapi.com/email', ...
console.log(...) doesn't make any sense here, since it will be executed after the Observable has been created as an object, but not after the ajax call has bee made.
If you want to output something after a response has been received, you have to move it inside subscribe
So in the end this website had the right answer. Also important to notice with the Angular2 Form validator to put the Async validators in the third (3) parameter and not together in an array in the second (2) parameter. That took me about 3 hours to figure out.
function checkEmail(control: Control){
let injector = ReflectiveInjector.resolveAndCreate([HTTP_PROVIDERS]);
let http = injector.get(Http);
return new Observable((obs: any) => {
control
.valueChanges
.debounceTime(400)
.flatMap(value => http.post('https://secretapi.com/email', JSON.stringify({ email: control.value })))
.map((res: Response) => res.json())
.subscribe(
data => {
if(data.success){
obs.next(null);
obs.complete();
} else {
obs.next({ 'invalidEmailAddress': true });
obs.complete();
}
}
);
});
}
The validator should look something like this, with the first validators checking on required and if it's actually an email address and the last doing an async call to the server to see if it's not already in use:
this.registerForm = this.formBuilder.group({
'email': ['', [Validators.required, ValidationService.emailValidator], ValidationService.emailAvailable],
});

how to refresh the text inside growl messages for protractor

I have been trying to test two scenarios, wherein, first, the user doesnt enter any password, and growl throws an error, and second, wherein the user enters wrong password. Both the scenarios throw an error message in a growl message box.
The problem is in protractor, where I'm checking for the error messages. The first one passes, but second one fails.
Below are the two test cases:
it("should validate password", function() {
browser.ignoreSynchronization = true;
emailElement.clear().sendKeys('admin#gmail.com');
pswrdElement.clear().sendKeys('');
element(by.css('.newRqst')).click().then(function() {
browser.wait(function() {
return element(by.css(".growl-item")).isPresent();
}, 10000).then(function() { //waiting 10 seconds for the growl to appear
expect(element(by.css("[ng-switch-default]"))
.getText()).toBe("missing password parameter");
});
});
});
it("should throw an error for incorrect email or password", function() {
browser.ignoreSynchronization = true;
emailElement.clear().sendKeys('admin#gmail.com');
pswrdElement.clear().sendKeys('1234');
element(by.css('.newRqst')).click().then(function() {
browser.wait(function() {
return element(by.css(".growl-item")).isPresent();
}, 10000).then(function() { //waiting 10 seconds for the growl to appear
expect(element(by.css("[ng-switch-default]"))
.getText()).toBe("Wrong email or password");
});
});
});
This throws an error for failure as:
Expected 'missing password parameter' to be 'Wrong email or password'.

Suppressing/Catching the ValidationError error from Mongoose

I have a static method setup that will verify if an object follows the schema of the model properly, and I've got the validation itself working just fine, but I can't get Mongoose to hide the ValidationError error that displays in the console.
The static method for the validation is:
fieldSchema.statics.testValidate = function( field ) {
return new Promise( ( res, rej ) => {
new this( field ).validate( err => {
if ( err ) return rej( err )
res( true )
} )
})
}
Then when I execute it:
Field.testValidate( fieldData )
.then(data => {
console.log('OK!', data)
})
.catch( err => {
console.error('FAILED:',err)
})
.finally(() => Mongoose.connection.close())
And like I said, I can get it to validate the data, but it will always show this error:
Unhandled rejection ValidationError: Field validation failed
at MongooseError.ValidationError ....
(Note: Im using Bluebird for my JS promises, incase it has anything to do with the then/catch somehow)
The script execution keeps going on with the code, so that means that it doesnt actually kill the script or anything, it just logs the error to the console. But since this function is meant to validate, its not really an "error", so is there a way to hide this from the console? (Just for this function, not for ALL Mongoose errors)
Thanks
validate already returns a promise so you don't need to wrap it in a new promise. The reason you see the error logged to the console is because of the fact that you're wrapping it in a new promise thus preventing the original promise from ever being caught i.e. Unhandled rejection.
fieldSchema.statics.testValidate = function(fieldData) {
return new this(fieldData).validate()
}