Sahi: Try-catch can't handle 'The parameter passed to xyz was not found on the browser" error? - try-catch

I run all my scripts through a .suite-file roughly in the following form:
_include("variables.sah");
_include("functions.sah");
$a = 0;
while($a<3) {
try {
_navigateTo($loginpage);
login($user, $password);
myFunction();
$a = 3
}
catch (e){
_navigateTo($loginpage);
login($user, $password);
//undo changes made by myFunction()
...
$a++;
if($a<3) {
_log("Try again");
}
else {
_log("Skip to next script");
}
}
}
function myFunction() {
//do this
...
}
Now all this runs perfectly fine, except for one thing: it doesn't repeat when it encounters a missing element which under normal circumstances would abort all scripts. It simply ignores the error and moves on to the next line of the suite. How do I make my script retry up to 2 times before moving on, if I don't know which part (if any) is going to fail and when?

Your code looks fine I guess.
One thing I can think of is that the exception is thrown in the catch block.
I made a simple script which works as intended:
var $errors = 0;
function trySet() {
try {
_setValue(_textbox("does not exist"), "");
} catch ($e) {
$errors++
_alert($errors);
}
}
for (var $i = 0; $i < 3; $i++) {
trySet();
}
Better figure out where exactly your script runs into problems and handle them with separate try-catch blocks accordingly. How you handle the exceptions is up to you but I guess it would be something like:
try {
login()
} catch ($e) {
// login failed, try again
}
try {
myfunction()
catch($e) {
revertMyFunction()
//try again
}
Maybe define your own exceptions to differently react to errors, have a look at this for more info on custom exceptions: Custom Exceptions in JavaScript
Regards
Wormi

Related

Would like to stop execution of code when a match is met

I created this service method in Angular JS which checks if an array of potential statuses(pendingApplications) match any of an array of set statuses(applicableStatuses). For this to work it meetsStatusCondition should return true after the first match occurs. Only 1 of the numbers in pendingApplications array needs to match and I'd like to end the execution of this function. Currently it's looping through every item in pendingApplications array
`containsApplicableStatus: function(pendingApplications, applicableStatuses) {
pendingApplications.forEach(function(status) {
if (applicableStatuses.includes(status)) {
return pendingApplications.meetsStatusCondition = true;
}
});
}`
This is a limitation with .forEach, you can't break out if it like you can with a for loop
Just a regular for loop will work
for (const status of applicableStatuses){
if (applicableStatuses.includes(status)) {
pendingApplications.meetsStatusCondition = true;
break //or return if you want to exit out of the enclosing function instead of just the loop
}
}
Often when you want to short-circuit a forEach like this, what you're really looking for is another method like find() or some().
containsApplicableStatus: function(pendingApplications, applicableStatuses) {
pendingApplications.meetsStatusCondition = pendingApplications.some(function(status) {
return applicableStatuses.includes(status)
});
}
There is no point in using forEach (which doesn't have a breaking option) if you could just use a regular for ... of loop instead:
containsApplicableStatus: function(pendingApplications, applicableStatuses) {
for (const status of pendingApplications) {
if (applicableStatuses.includes(status)) {
pendingApplications.meetsStatusCondition = true;
break;
}
}
}
However, even this seems a bit too complicated, you could just set meetsStatusCondition to the result of some:
containsApplicableStatus: function(pendingApplications, applicableStatuses) {
pendingApplications.meetsStatusCondition =
pendingApplications.some(status => applicableStatues.includes(status));
}
I do wonder if it makes sense to set a non-index property on your array though, maybe rethink that. This works but it's usually not something you'd expect on an array, and it will be lost if you convert that array to JSON for instance.

Make a while loop, loop for 1 second in Dart/Flutter

I am trying to make a while loop loop a statement exactly for one second after which it stops. I have tried this in DartPad, but it crashes the browser window.
void main(){
var count = 0.0;
bool flag = true;
Future.delayed(Duration(seconds: 1), (){
flag = false;
});
while (flag){
count++;
}
print(count);
}
Am I doing something wrong?
I like how you are trying to figure Futures out. I was exactly where you were before I understood this stuff. It's kind of like threads, but quite different in some ways.
The Dart code that you wrote is single threaded. By writing Future.delayed, you did not start a job. Its execution won't happen unless you let go of the thread by returning from this main function.
Main does not have to return if it is marked with async.
Two actions have to run "concurrently" to be able to interact with each other like you are trying to do. The way to do it is to call Future.wait to get a future that depends on the two futures. Edit: Both of these actions have to let go of execution at every step so that the other can get control of the single thread. So, if you have a loop, you have to have some kind of await call in it to yield execution to other actions.
Here's a modified version of your code that counts up to about 215 for me:
Future main() async {
var count = 0.0;
bool flag = true;
var futureThatStopsIt = Future.delayed(Duration(seconds: 1), (){
flag = false;
});
var futureWithTheLoop = () async {
while (flag){
count++;
print("going on: $count");
await Future.delayed(Duration(seconds: 0));
}
}();
await Future.wait([futureThatStopsIt, futureWithTheLoop]);
print(count);
}

How to stop executing a loop (say if loop once it finds a match) in Protractor for AngularJS applications?

I am writing test cases using protractor for AngularJS Application. I want to stop an if loop once it finds the value. Is there any equivalent function available that I can use to stop executing the loop further in Protractor, like we have break in C.
break is a javascript instruction:
function testBreak(x) {
var i = 0;
while (i < 6) {
if (i == 3) {
break;
}
i += 1;
}
return i * x;
}
A complete reference of the language is available on the mozilla developer network with a list of all the statements.
Brendan Eich wrote:
JavaScript borrows most of its syntax from Java, but also inherits
from Awk and Perl, with some indirect influence from Self in its
object prototype system.
NB: This question is neither specific to protractor, nor angular.js nor to automation.
you also have the break statement in javascript.
There is break/continue in javascript:
http://www.w3schools.com/js/js_break.asp
This is my code and i want break after if statement because text has been match i dont want to again go to else block
for (i = 0; i <row.length; i++)
{
var obj_dn_ocnele=obj_dn_ocndrpdown_elements.get(i).getText().then(function(text) {
var test_var1 = text.trim();
console.log(test_var1);
outer:{
if (test_var1 == var_ocn_id)
{
log.info(var_ocn_id +"ocn exist");
break outer;
}
else
{
log.error(var_ocn_id +"ocn not exist");
break outer;
}
}
});
}

Node isDirectory() not working properly or i am missing somenthing

I want to get all names of files and directories from path and recognize them as files and directories. but When i run my code sometimes it works and somentimes it shows that directories are files. Here is the code
socket.on('data',function(path){
fs.readdir('path',function(err, data) {
var filestatus=[];
var z=0;
var i=data.length-1;
data.forEach(function(file){
fs.stat(file, function(err, stats) {
filestatus[z]=stats.isDirectory()
if (z==i){
socket.emit('backinfo',{names:data,status:filestatus});
}
z++;
})
})
})
})
During tests i realized that when i slow down data.forEach loop (using console.log(something) it works better(less miss). And this is strange.
This is about 96% incorrect, thank you to JohnnyHK for pointing out my mistake, see the comments below for the real problem / solution.
Because the fs.stat() function call is asynchronous, the operations on the filestatus array are overlapping. You should either use the async library as elmigranto suggested, or switch to using fs.statSync.
More details on what's happening:
When you call fs.stat(), it basically runs in the background and then immediately goes onto the next line of code. When it has got the details of the file, it then calls the callback function, which in your code is the function where you add the information to the filestatus array.
Because fs.stat() doesn't wait before returning, your program is going through the data array very quickly, and mutliple callbacks are being run simultanously and causing issues because the z variable isn't being incremented straight away, so
filestatus[z]=stats.isDirectory()
could be executed multiple times by different callbacks before z gets incremented.
Hope that makes sense!
you are using for statement in NODEJS and this will work if turned the For Statement to recursive function please see the attached code for help
function load_Files(pat,callback) {
console.log("Searching Path is: "+ph);
fs.readdir(pat,(err,files)=>
{
if(err)
{
callback(err);
}
else
{
var onlydir=[];
var onlyfiles=[];
var d=(index)=>
{
if (index==files.length)
{
console.log("last index: "+ index);
var ar=[];
ar.concat(onlydir,onlyfiles);
callback(null,ar);
return;
}
fs.stat(files[index],(err,status)=>
{
console.log("the needed file " +files[index]);
if (status.isDirectory())
{
onlydir.push(files[index]);
}
else
{
onlyfiles.push(files[index]);
}
console.log("only Directory: "+onlydir.length);
console.log("index: "+ index);
d(index+1);
}
)
}
d(0);
}
});
}

Else-part of code being executed, even if string.equals(otherstring) is true

The problem with this code seems to be that the 'else' part of the if-statement is executed, even if the variables match (so 'if' is true). Any advice, please?
Thanks!
public void CheckInstalledDBVersion() throws NullPointerException, IOException {
try {
//TRY TO OPEN DATABASE AND READ VERSION
//WRITE VERSION TO InstalledDBversion
} catch(RuntimeException e) {
//IF TABLE COULD NOT BE QUERIED
//SET InstalledDBversion to Bogus value
InstalledDBversion = "00";
Log.d("RTE", ".. but we've catched it!");
} finally {
if (InstalledDBversion.equals(PackedDBversion)){
// Installed DBVersion == Packed DBVersion .. nothing happens
}
else
showDialog(DBCHECKFAILDIALOG);
initialiseDatabase = false;
copyDB();
}
}
So, when I execute, copyDB(); gets called even if InstalledDBversion.equals(PackedDBversion) == true
else
showDialog(DBCHECKFAILDIALOG);
initialiseDatabase = false;
copyDB();
Fixed indentation for you. copyDB is outside of the if/then/else block. Use an IDE with code formatting.
What lines are supposed to be included in the else block? the showDialog(DBCHECKFAILDIALOG) is only included. Are you missing a set of {} for the else block?

Resources