Can I create a custom error at Cypress.io? - cypress

I have tried all sorts of techniques but none create a custom error message.
Has anyone managed to crack the problem?
const { statusCode, body } = serverRequest.response;
if (statusCode !== 200 || statusCode !== 201) {
const { errorKey, subErrorKey, errorMsg } = body?.error || {};
Cypress.runner.stop();
throw new Error(`${errorKey}->${subErrorKey}-${errorMsg}`);
}

throw new Error(...) by itself will stop the current current test, or all tests if it's in a before() or beforeEach().
before(() => {
...
const { statusCode, body } = serverRequest.response;
if (statusCode !== 200 || statusCode !== 201) {
const { errorKey, subErrorKey, errorMsg } = body?.error || {};
throw new Error(`${errorKey}->${subErrorKey}-${errorMsg}`);
}
...
})
Cypress will stop with something like "because the error occurred in 'before()' we will not perform any tests".

Throwing the new error is enough to stop the case. I think your code just needs to remove Cypress.runner.stop();, because it shuts everything down.
const { statusCode, body } = serverRequest.response;
if (statusCode !== 200 || statusCode !== 201) {
const { errorKey, subErrorKey, errorMsg } = body?.error || {};
throw new Error(`${errorKey}->${subErrorKey}-${errorMsg}`);
}

Related

How to get error from backend with axios?

I'm trying to display an error I recieve in my backend to the user in my JSX frontend file.
This is the initial call from frontend
dispatch(createGoal({ values }))
Goalslice, directly called from JSX:
export const createGoal = createAsyncThunk(
'goals/create',
async (goalData, thunkAPI) => {
try {
const token = thunkAPI.getState().auth.user.token
return await goalService.createGoal(goalData, token)
} catch (error) {
const message =
(error.response &&
error.response.data &&
error.response.data.message) ||
error.message ||
error.toString()
return thunkAPI.rejectWithValue(message)
}
}
)
Goalservice, directly called from goalslice:
const createGoal = async (goalData, token) => {
const config = {
headers: {
Authorization: `Bearer ${token}`,
},
}
const response = await axios.post(API_URL, goalData, config)
return response.data
}
Goalcontroller, my backend:
const setGoal = asyncHandler(async (req, res) => {
const goals = await Goal.find({ user: req.user.id })
var count = Object.keys(goals).length
if(count >2){
res.status(400)
throw new Error('Maximum of 3 trackers per user')
}
if (!req.body.values) { //if this isnt there. check if the body is there.
res.status(400) //This is an error
throw new Error('Please add a date field') //this is express error handler
}
console.log(req.body.values.dates)
const goal = await Goal.create({
values: req.body.values.dates, //get from request body
permit: req.body.values.permits,
numpermit: req.body.values.num,
user: req.user.id,
})
res.status(200).json(goal)
})
I want to display this error:
throw new Error('Maximum of 3 trackers per user')
I tried a try/catch method, but I'm very new to this and I feel like i'm missing a very key point in how it all fits together.
This is my custom error handler if it helps:
const errorHandler = (err, req, res, next) => { //overwrite express error handler, next to handle any new req
const statusCode = res.statusCode ? res.statusCode : 500 //500 is server error. conditional
res.status(statusCode)
res.json({
message: err.message,
stack: process.env.NODE_ENV === 'production' ? null : err.stack, //gives additional info if in development mode : is else
})
}
module.exports = { //export for others to use
errorHandler,
}

How to translate a text for a toast message

I want to use translation for a toast message. How can I do it?
See the code below:
fetch(request).then(response => {
if (response.status < 200 || response.status > 300) {
// throw new Error(response.statusText);
} // if
return response.json();
}).then (({token, message}) => {
if (token) {
localStorage.setItem('token', token);
} else {
throw new Error((translate('pos.search')));
} // else
});

Retrieving of Restful web service values in android for Titanium

We are using the same restful web service code from serviceutility.js for both android and ios. But the service is getting hit and values are retrieved only in ios. The same code is not working in android and we are getting the following error:
[ERROR] : TiExceptionHandler: (main) [2,821093] - In alloy/controllers/home.js:25,32
[ERROR] : TiExceptionHandler: (main) [0,821093] - Message: Uncaught TypeError: Cannot read property 'status' of null
[ERROR] : TiExceptionHandler: (main) [0,821093] - Source: if ("1" == response.status) alert(response.message); else if ("0"
[ERROR] : V8Exception: Exception occurred at alloy/controllers/home.js:25: Uncaught TypeError: Cannot read property 'status' of null.
Titanium SDK is 5.1.2 GA
exports.login = function(user, cb) {
var response = null;
if (Ti.Network.online) {
var xhr = Ti.Network.createHTTPClient({
timeout : 10000,
validatesSecureCertificate : false
});
xhr.onload = function() {// Onload
var responseTxt = this.responseText == '' ? '{}' : this.responseText;
try {
response = JSON.parse(responseTxt);
cb(response, 'SUCCESS');
} catch(e) {
cb(response, 'ERROR');
}
};
xhr.onerror = function(e) {
if (xhr.status === 0) {
cb(response, 'TIMEDOUT');
} else {
cb(response, 'ERROR');
}
};
url = "https://";
var postData = {
employeeId : user.employeeId,
password : user.password
};
xhr.open('POST', url);
xhr.setTimeout(10000);
xhr.setRequestHeader('employeeId', user.employeeId);
xhr.setRequestHeader('password', user.password);
xhr.send();} else {
cb(response, 'NO_NETWORK');
}};
The below code is for index.js file where the actual retrieval of values happen.
if (Ti.Network.online) {
loginUtil.login(user, function(response, status) {
Ti.API.info("status----" + status);
if (response.status == "0") {
Ti.API.info("status== " + response.status);
Ti.App.role = response.role;
Alloy.createController('home', {employeeId:$.userTextField.value,password:$.passwordTextField.value,from:"index"}).getView().open();
} else if (response.status == '1') {
alert(response.message);
} else {
alert("Please enter the correct credentials");
}
});
}
Please help us on this.
Looks like you are ONLY returning a string value instead of the entire response object. Then in your controller you attempt to access the .status property of the response object.
//this line returns the string responseTxt
response = JSON.parse(responseTxt);
Try returning the entire response object instead.
response = JSON.parse(this);
Then in your index.js controller use/ display the status property
alert(response.status);
Your index.js expected response to be an object, but that is only the case where you call callback like this:
response = JSON.parse(responseTxt);
cb(response, 'SUCCESS');
All other places where you call callback the response variable is null, since that is what you initialise it with on the second line.
Your callback returns two parameters, response & status, the second param is never used.
From reading the login function code, you only get to access the response object if status == "SUCCESS"
if(status === "SUCCESS"){
if (response.status == "0") {
Ti.API.info("status== " + response.status);
Ti.App.role = response.role;
Alloy.createController('home', {employeeId:$.userTextField.value,password:$.passwordTextField.value,from:"index"}).getView().open();
} else if (response.status == '1') {
alert(response.message);
} else {
alert("Please enter the correct credentials");
}
}
else {
alert("whoops, please try again !"); // a more generic message.
}

How to re-call an adapter procedure after session expiration?

While calling a protected procedure in an adapter (getMyRecords) and the server session is expired, the application re-login to get a new session, but it doesn't call getMyRecords again.
Below is a sample code:
Adapter XML file
<procedure name="getMyRecords" securityTest="appSecurityTest" />
challengeHandler JS file
challengeHandler.isCustomResponse = function(response) {
if (!response || !response.responseJSON || response.responseText === null) {
return false;
}
if (typeof (response.responseJSON.authRequired) !== 'undefined') {
//Should enter automatically to handleChallenge but not always
return true;
} else {
return false;
}
};
After that this will execute the below code (handle challenge) :
challengeHandler.handleChallenge = function(response) {
var hasGlobalHeader = (WL.Client.__getGlobalHeaders()['ENC-USER'] != undefined);
if(hasGlobalHeader ){ //Re-login response
//this will invoke the relogin procedure to get a new session and to authenticate the user
challengeHandler.handleRelogin(response);
}else{
...
}
};
challengeHandler.handleRelogin = function(response){
var authRequired = response.responseJSON.authRequired;
if (authRequired == true) {
var input = {
adapter: "AuthenticationAdapter",
procedure: "autoLogin",
parameters: [localStorage.getItem('encryptedUser'), lang]
};
WL.Client.invokeProcedure(input, {
onSuccess: function(response){
$logger.log('service :: autoLoginSuccess :: response : ', response);
def.resolve(response);
},
onFailure: function(err){
$logger.log('service :: autoLoginFailure :: err : ', err);
def.reject(err);
}
});
}else{
//InitContext
initContext(response);
goHome();
//challengeHandler.activeRequest = null ;
}
};
The problem is when calling submitSuccess it does not issue the original request but calls infinitely autoLogin procedure.
Make sure that for every time that handleChallenge is called, either submitSuccess or submitFailure is called.
Until you call one or the other, the framework does not know that you finished answering the challenge. Never leave a challenge unanswered.
Also I think that instead of:
if (typeof (response.responseJSON.authRequired) !== 'undefined') {
You should try
if (typeof (response.responseJSON.authRequired) !== 'undefined' && response.responseJSON.authRequired == true) {

Exception nette-ajax extension error in IE8

I have a problem with an exception nette-ajax extension in IE8. Does anybody know, what does it mean and how fix it?
this.ext = function (name, callbacks, context) {
if (typeof name === 'object') {
inner.ext(name, callbacks);
} else if (callbacks === undefined) {
return inner.contexts[name];
} else if (!callbacks) {
$.each(['init', 'load', 'prepare', 'before', 'start', 'success', 'complete', 'error'], function (index, event) {
inner.on[event][name] = undefined;
});
inner.contexts[name] = undefined;
} else if (typeof name === 'string' && inner.contexts[name] !== undefined) {
throw "Cannot override already registered nette-ajax extension '" + name + "'.";
} else {
inner.ext(callbacks, context, name);
}
return this;
};
in console.log(name) is result redirect

Resources