I am relatively new to development so please forgive me if some of this seems rather amateurish. Part of my reason for posting the question is to help nudge me to the answer, part is to make sure I'm following good coding practice.
The challenge -
I'm using Java & Selenium to check a very large, dynamically populated table. I need to find a specific list of elements where the text matches a case-sensitive String -
List<WebElement> AllPaths = getCurrentDriver().findElements(By.xpath("//*[text()[contains(.,'" + fixedString + "')]]"));
The table I'm checking is basically a large calendar-style grid. If I don't find evidence of fixedString, I then want to iterate back one month at a time until I DO find the fixedString.
The problem -
The code above returns an exception if it cannot find an element. My first thought was to setup a while loop, trying/catching the exception and then repeating until exceptions stopped. However this feels wrong to me - I don't think I should be essentially "swallowing" exceptions. That said, I'm not sure what the correct way of trying to find this element is that doesn't lead to an exception if it fails to locate it.
Am I right in thinking it's a bad idea to write code that you know causes an exception and then simply swallow it and move on?
Hope this makes sense, as I say I'm a beginner so please be gentle :)
You can try something like -
if(AllPaths.size()>0){
//logic when elements found with fixed string
}else{
//logic to iterate over another month
}
Also, your statement seems wrong to me. It should be -
List<WebElement> AllPaths = getCurrentDriver().findElements(By.xpath("//*[contains(text(),'" + fixedString + "')]"));
findElements doesn't throw exception this way. It will return empty if no elements located. The exception seems due to incorrect statement that you are using to find elements.
The code above returns an exception if it cannot find an element.
The documentation says findElements returns an empty list when no elements are found. It should not throw any exception in this case. Is it possible that you by mistake used findElement instead of findElements? What type of exception is thrown and what is the message?
You shouldn't need to catch exceptions here. You are right though that control flow using exceptions should be avoided and that swallowing exceptions is bad. On the other hand frameworks don't always let you write code the way you want so sometimes exceptions have to be made.
Related
Slightly odd question but I'm practicing exception handling with try catch blocks at the minute and I'm trying to generate an exception caused by a user entering values that are not on a predefined list. I am unsure of how to generate the errors needed to work on the exception handling. The simplest possible example to generate the error is fine, I'm just using months of the year. I have tried adding them to an arraylist and running a months.contains() line but it's not giving me any errors if I enter something that's not there.
I'm normally fantastic at generating exceptions, but somethings changed
You can use an enum for this.
Declare this outside you method.
enum MONTHES {
JAN, FEB, MAR;
};
Inside your method do this.
MONTHES.valueOf("FOO");
This will throw an java.lang.IllegalArgumentException
The first xpath is working whereas the second not:
First:
"//*[#id='j_idt46:j_username']";
Second:
"//*[contains(#id,'username']";
Why?
To what could be figured out of the information provided, the way you are using contains is possibly inappropriate :
As mentioned by #TuringTux - //*[contains(#id,'username')] could be the possible change if the same lined goes as it is in your code.
Also a good practice to follow in //*[contains(#id,'username')] , would be to replace * by an element type in html.
And lastly there could be chances when you are trying to access elements using //*[contains(#id,'username')], you may be ending up getting a list of these similar WebElements while you might be trying to access only a single at the same time.
I have the following code for logging all the errors after every command I run in cmd with my tool. (It runs p4 integrate commands, about 1000-1500/task)
if (errorArrayList.size() > 0) {
LoggerSingleton.I.writeDebugInfoTimeStampedLog("[INFO-CMD] CommandExecuter.java -> runAndGetResults: errors happened while running the following command: [ " + commandResultBean.getCommand() + " ]");
for (int i = 0; i < errorArrayList.size(); i++) {
LoggerSingleton.I.writeDebugErrorTimeStampedLog(errorArrayList.get(i));
commandResultBean.addToCLI_Error(errorArrayList.get(i));
}
LoggerSingleton.I.writeDebugInfoTimeStampedLog("[INFO-CMD] CommandExecuter.java -> runAndGetResults: Listing errors of command [" + commandResultBean.getCommand() + "] finished");
}
The feature that I'm working on right now is check the error I get, and if that's on a predefined error list (list of errors that doesn't matter, and in fact not real errors, for example "all revision(s) already integrated") do nothing else, but when it's a "real" error, write it to an other log file too (Because these debug logs way too long for the users of the tool, it's made for the developers more likely).
The question is, what is the best way for this?
I want to avoid big deceleration. I have many commands, but the number of errors less then the commands, but that is not unusual at all that I get 700-800 "irrelevant" errors in one task.
I will use another class to make the I/O part, and that is not a problem to extend the running time in case we catch a "real" error.
The list is constant, it is okay if it can be modified only by coding.
At the moment I don't know what type to use (2-3 single Strings, List, Array ...). What type should I use? I never used enums in Java before, in this one should I?
I guess a for or foreach and errorArrayList.get(i).contains(<myVariable>)in a method is the only option for the checking.
If I'm wrong, there is a better way to do this?
EDIT
If I have an ArrayList<String>called knownErrors with the irrelevant errors (can define only parts of it), and I use the following code will better performance than a method wrote above? Also, can I use it if I have only parts of the String? How?
if (errorArrayList.removeAll(knownErrors) {
//do the logging and stuff
}
ArrayList itself has a method removeAll(Collection c) which removes all the elements which are matching with input collection elements. Below program show it evidently. So if you have the known error to be skipped in arraylist and pass it to removeall method it will remove the known errors and errorArrayList will have only new errors.
I am using NetBeans 7.3.1 and JavaFX 2.2.
I am getting an error which says just '2' (not like NullPointerException, etc). When I change some 2-d Array values then error is some other number.
StackTrace :
Executing com.javafx.main.Main from (my project path).jar using platform D:\Java\jdk1.7.0_25/bin/java
2 this is my error. sometimes 6,5 ,etc
file:/(my project path).jar!/<project name>/SelectionWindow.fxml
at <project name>.SelectionWindowController.attachBrandImagesAndNamesToTiles(SelectionWindowController.java:92)
at <project name>.SelectionWindowController.initialize(SelectionWindowController.java:33)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2152)
at ..... all the trailing trace
Explain me this error and how to solve it.
Well, seeing the exception is thrown from this line:
brandNames[i][j] = new Label(DataInterface.getBrandName(i, j));
It may be reasonable to assume you have your array elements out of range, causing it to throw an OutOfBoundsException 2 if for example you tried to reach element 2 from the array but for example it only has 1 element.
Without your full stack trace it is hard to say for sure though.
This is difficult to say. The stack trace shows the error on line 92, which is this:
brandNames[i][j] = new Label(DataInterface.getBrandName(i, j));
The javafx.scene.control.Label constructor doesn't appear to throw any exceptions (see http://docs.oracle.com/javafx/2/api/javafx/scene/control/Label.html#Label%28java.lang.String%29). I would say
Put a try/catch block around the entire inner loop.
In the catch statement, use reflection to find out what exactly the class type of the exception is (post back if you don't know how, and I'll write the code for you)
And then also write out the message from the caught exception.
I have an ANTLR Grammar that is in the form:
A - B: more,things
However sometimes, either A or B can be missing such as:
- B: more, things //Skip
A - : some, other, things //Skip
C - D: yet, more, things //Read this one and following
E - F: things
I want ANTLR to skip over those lines (where either side of - is missing) and continue processing the rest.
Basically, something like that
- B: more, things {if (!hasBothParts()) { continueAtNextLine();} };
From the book, I provided a #rulecatch and this catch after my appropriate Parser block:
catch[RecognitionException re]{
reportError(re);
consumeUntil(input, NEWLINE);
input.consume();
}
EDIT 2 - I tried doing this instead:
while (input.LA(1) != 6){
input.consume();
}
This worked as expected. 6 is the token identifier for "NEWLINE" for me. I don't know how to do a comparison like input.LA(1) != "\n" or something similar. I know it's not correct to do it this way, I am just experimenting. If you know the right way, please tell me! :)
But this works, unlike the first loop. I suspect consumeUntil is perhaps not seeing the NEWLINE on channel Hidden.
The NullPointer seems to be caused by the input fast-forwarding to EOF, and hence, the tree grammar is hitting a Null when it's doing input.LT(1).
However, in doing so, I get a NullPointerException in my tree grammar:
Exception in thread "main" java.lang.NullPointerException
at org.antlr.runtime.tree.BaseTreeAdaptor.isNil(BaseTreeAdaptor.java:70)
at org.antlr.runtime.tree.CommonTreeNodeStream.nextElement(CommonTreeNodeStream.java:93)
at org.antlr.runtime.misc.LookaheadStream.fill(LookaheadStream.java:94)
at org.antlr.runtime.misc.LookaheadStream.sync(LookaheadStream.java:88)
at org.antlr.runtime.misc.LookaheadStream.LT(LookaheadStream.java:119)
....
The behavior I want is for the parser to skip over the lines missing components and proceed with the remaining lines. The tree parser should not be a problem, I assume?
The ANTLR book does not mention anything regarding this issue.
Also, I think the ANTLR Error Recovery mentions something along those lines but the solution provided is fairly complex/ugly and dates back to 2004. So, is there a better way of doing this relatively simple thing in ANTLR?
Thank you.
EDIT If this helps, the error was caused by this line in the generated tree grammar:
retval.start = input.LT(1);
Which is, I assume, being called with nothing. I.e. LT(1) is returning Null, since it skipped over.