I have this line of Code
try {
String txtText = article.getTxtText().toString();
if (StringUtils.hasText(article.getTxtText().toString())){
textPropertyList.add(txtText);
}
String txtLongText = article.getObjLongTextData().toString();
if (StringUtils.hasText(txtLongText)){
textPropertyList.add(txtLongText);
}
String txtShortText = article.getObjShortTeaserData().toString();
if (StringUtils.hasText(txtShortText)) {
textPropertyList.add(txtShortText);
}
} catch (NullPointerException e) {
}
It is possible, that only one of the three properties are set. But if one property isnt set, I get this NullpointerException. I catch it, but then the try-Block isnt continued.
So e.g. if the article.getTxtText() method returns null, I dont get the txtLongText and txtShortText Strings either, although at least one of them has a not empty String set.
So the question is, how can I continue the try-block although there's is an Exception caught?
Thanks a lot.
You should either use 3 try-catch blocks or just use a null-check around every case.
if (article.getTxtText() != null) {
// do part 1
}
if (article.getObjLongTextData() != null) {
// do part 2
}
I would imagine that the correct approach to this is to have three try/catch blocks around each point of code. The whole point of a try block is that you are trying the code as a lump and if it fails anywhere you abandon it. For what you are describing you would need three try/catches around each possible point of failure.
That having been said you are probably better off testing for null rather than relying on exception handling to do that. Exception handling should be for exceptionalm unforeseen events, not for flow control in a program.
If you must do this with exceptions (and I don't think you should), then you need to have 3 separate try/catch blocks:
try {
String txtText = article.getTxtText().toString();
if (StringUtils.hasText(article.getTxtText().toString())){
textPropertyList.add(txtText);
}
} catch (NullPointerException e) {}
try {
String txtLongText = article.getObjLongTextData().toString();
if (StringUtils.hasText(txtLongText)){
textPropertyList.add(txtLongText);
}
} catch (NullPointerException e) {}
try {
String txtShortText = article.getObjShortTeaserData().toString();
if (StringUtils.hasText(txtShortText)) {
textPropertyList.add(txtShortText);
}
} catch (NullPointerException e) {}
Once an exception is thrown in your code you cannot restart execution in the middle of the try block.
Having said that I would always prefer to detect the null pointer with an if test rather than relying on exception handling for this non-exceptional condition.
do defensive programming ,check for nulls.
if ( variable != null ){
...
}
The simplest and better approach from my point of view would be break the try - catch block in three different try-catch block, something like the following :
try {
String txtText = article.getTxtText().toString();
if (StringUtils.hasText(article.getTxtText().toString())){
textPropertyList.add(txtText);
}
} catch (NullPointerException e) {
//Handle Exception
}
try {
String txtLongText = article.getObjLongTextData().toString();
if (StringUtils.hasText(txtLongText)){
textPropertyList.add(txtLongText);
}
} catch (NullPointerException e) {
//Handle Exception
}
try {
String txtShortText = article.getObjShortTeaserData().toString();
if (StringUtils.hasText(txtShortText)) {
textPropertyList.add(txtShortText);
}
} catch (NullPointerException e) {
//Handle Exception
}
I'd recommend a different design:
private void addProperty(Object property, Collection<String> properties) {
if (property == null) {
return;
}
String textProperty = property.toString();
if (StringUtils.hasText()) {
properties.add(textProperty);
}
}
Usage:
addProperty(article.getTxtText());
// ...
Why are you doing this in a try / catch, just use simple if
if ( txtText != null ){
...
}
if ( txtLongText != null ){
...
}
Related
There is a method which can:
throw an error
return null
I need to throw a user friendly exception to upper level in the both cases. What is the most elegant way for it? The brute force is:
try {
result = callMethod();
} catch (SomeException e) {
throw new UserFiendlyException("cannot process you, try again pls");
}
if (result == null) {
throw new UserFiendlyException("cannot process you, try again pls");
}
UPD 1: kotlin is accepted and preferable (but I'm also curious how could it be in Java)
UPD 2: Please, don't suggest the use of exceptions for control flow is an anti-pattern: https://softwareengineering.stackexchange.com/questions/189222/are-exceptions-as-control-flow-considered-a-serious-antipattern-if-so-why
If callMethod() is your own method, you could update that to perform the null check internally and throw the error...
function callMethod() {
const responseFromService = null;
if (responseFromService == null)
throw new SomeException(`Expected a valid response from the service but got null.`);
}
try {
result = callMethod();
}
catch (SomeException e) {
throw new UserFiendlyException("cannot process you, try again pls");
}
You can also try the null coalescing operator...
try {
result = callMethod() ?: throw new SomeException(`Escape!`);
}
catch (SomeException e) {
throw new UserFiendlyException("cannot process you, try again pls");
}
Or just keep it simple and check for null within the try...
try {
result = callMethod();
if (result == null) throw new SomeException(`Escape!`);
}
catch (SomeException e) {
throw new UserFiendlyException("cannot process you, try again pls");
}
Edit: Answer originally had the nullish coalescing operator as an option, but the question is for Java, not JavaScript. My bad.
Edit (2): Turns out there is a nullish coalescing operator in Kotlin; option restored.
try...catch and throw are expressions in Kotlin, so you can do:
val result =
try {
callMethod()
} catch (e: SomeException) {
null
} ?: throw UserFiendlyException("cannot process you, try again pls")
The try...catch will produce null if either callMethod returns null. or if an exception occurred. We check if it is null using ?:, and if it is, we throw the user friendly exception.
result will end up having a non nullable type.
If one method work and other doesn't then how do I make the code try a alternative method?
Here is the code
1st method
driver.findElement(By.id("com.simplemobiletools.gallery:id/dir_thumbnail")).click();
driver.findElement(By.id("com.simplemobiletools.gallery:id/medium_thumbnail")).click();
2nd method
driver.findElement(By.id("com.offerup:id/circle")).click();
driver.findElement(By.id("com.offerup:id/done")).click();
If the first method doesn't work I want it to go ahead and try the second method but, I don't know what command to use for this.
I am not very experienced at programming so please bear with me.
You can use try catch block for this purpose :
try {
driver.findElement(By.id("com.simplemobiletools.gallery:id/dir_thumbnail")).click();
driver.findElement(By.id("com.simplemobiletools.gallery:id/medium_thumbnail")).click();
catch (Exception e) {
driver.findElement(By.id("com.offerup:id/circle")).click();
driver.findElement(By.id("com.offerup:id/done")).click();
}
you can give a specific exception too, for example "ElementNotFoundException" or "ElementNotVisibleException" in your catch parameter type
I assume by "doesn't work" you mean the element wasn't found. Two options:
According to the documentation, findElement raises a NoSuchElementException if the element isn't found. So you can continue to use findElement and catch the exception via try/catch.
Alternately, use findElements, which returns a List, and branch based on whether any were found. As LuisGP pointed out, avoiding exceptions is often helpful.
Option 1:
try {
driver.findElement(By.id("com.simplemobiletools.gallery:id/dir_thumbnail")).click();
driver.findElement(By.id("com.simplemobiletools.gallery:id/medium_thumbnail")).click();
} catch (NoSuchElementException e) {
driver.findElement(By.id("com.offerup:id/circle")).click();
driver.findElement(By.id("com.offerup:id/done")).click();
}
Or if you meant to handle those one-by-one:
try {
driver.findElement(By.id("com.simplemobiletools.gallery:id/dir_thumbnail")).click();
} catch (NoSuchElementException e) {
driver.findElement(By.id("com.offerup:id/circle")).click();
}
try {
driver.findElement(By.id("com.simplemobiletools.gallery:id/medium_thumbnail")).click();
} catch (NoSuchElementException e) {
driver.findElement(By.id("com.offerup:id/done")).click();
}
Option 2 (if you want to handle them one-by-one, you should be able to tweak if you want to branch on just the first result):
List<WebElement> elements;
elements = driver.findElements(By.id("com.simplemobiletools.gallery:id/dir_thumbnail"));
if (element.size() == 0) {
driver.findElement(By.id("com.offerup:id/circle")).click();
} else {
elements.get(0).click();
}
elements = driver.findElements(By.id("com.simplemobiletools.gallery:id/medium_thumbnail"));
if (elements.size() == 0) {
driver.findElement(By.id("com.offerup:id/done")).click();
} else {
elements.get(0).click();
}
You can try click on an element out of 4 given elements which is visible and clickable. It will make you to safe to clicking on element after catching exception and good practice to follow. It will throw exception only when no element will be found out of 4 and it is valid case.
MobileElement A = driver.findElement(By.id("com.simplemobiletools.gallery:id/dir_thumbnail"));
MobileElement B = driver.findElement(By.id("com.simplemobiletools.gallery:id/medium_thumbnail"));
MobileElement C = driver.findElement(By.id("com.offerup:id/circle"));
MobileElement D = driver.findElement(By.id("com.offerup:id/done"));
public void clickOnElement() {
try {
if(A.isDisplayed() && A.isEnabled())
{
A.click();
}
if(B.isDisplayed() && B.isEnabled())
{
B.click();
}
if(C.isDisplayed() && C.isEnabled())
{
C.click();
}
if(D.isDisplayed() && D.isEnabled())
{
D.click();
}
}catch (Exception e) {
e.printStackTrace();
}
}
Just call 'clickOnElement' method in your test case.
I have a Java method like below:
private boolean getBooleanProperty(String property, String defaultValue) {
boolean result = false;
try {
result = Boolean.parseBoolean(properties.getProperty(property, defaultValue));
} catch (IllegalArgumentException | NullPointerException e) {
}
return result;
}
I know that the way I am handling the exceptions in above method is not correct and looking for the way to have those more aligned with the Java standards and best practices.
Similarly for the method below:
public void getStatusAndAnnotation(ITestResult result) {
try {
HashMap<Object, Object> map = new HashMap<>();
Method method = result.getMethod().getConstructorOrMethod().getMethod();
TestInfo annotation = method.getAnnotation(TestInfo.class);
try {
//add id removing the first character of the annotation (e.g. for C12034, send 12034)
if(annotation!=null) {
map.put("id",annotation.id().substring(1));
}
}catch (NullPointerException e){
e.printStackTrace();
}
if (result.getStatus() == ITestResult.SUCCESS) {
map.put("result", 1);
} else if (result.getStatus() == ITestResult.FAILURE) {
map.put("result", 9);
} else if (result.getStatus() == ITestResult.SKIP) {
map.put("result", 10);
}
if (annotation != null) {
if(annotation.trDeploy() && !map.get("id").equals(null) && !map.get("id").toString().isEmpty())
{
ApiIntegration.addTestResult(map);
}
else System.out.println("Deploying result was canceled, because test has annotation \"trDeploy: false\" or \"id\" has no value");
}
} catch (SecurityException | IOException
| ApiException | NullPointerException e) {
e.printStackTrace();
}
}
How do I handle these different exceptions to align with the best practices?
What I typically do is let the compiler/IDE tell me what exceptions I need to catch unless you want to catch an exception for a specific reason. That way, I can code without catching unnecessary exceptions and my code is cleaner.
These type of Exceptions are called Checked Exceptions
"In the Java class hierarchy, an exception is a checked exception if
it inherits from java.lang.Exception, but not from
java.lang.RuntimeException. All the application or business logic
exceptions should be checked exceptions."
Example:
try
{
// open a file (Compiler will force to either catch or throw)
}
catch (IOException ioe)
{
ioe.printStackTrace();
// need to make a decision on what to do here
// log it, wrap it in a RuntimeException, etc.
}
As for Unchecked Exceptions
"Unchecked, uncaught or runtime exceptions are exceptions that can be
thrown without being caught or declared"
Example:
String x = null;
// this will throw a NullPointerException
// However, you don't need to catch it as stated in some the comments
x.toString();
What you should do is prevent it
if (x == null)
{
x = "some default value"; // prevent the exception from happening.
}
x.toString();
Does this mean you should never catch a RuntimeException
No, of course not. It depends on the scenario.
Take this example:
String number = "12345";
// You don't know if number is a valid integer until you parse it
// If the string is not a valid number, then this code will
// throw an Exception
int i = Integer.parseInt(number);
Instead you can catch a NumberFormatException. Again, this is a form of prevention.
int i = 0; // some default
try
{
i = Integer.parseInt(number);
}
catch (NumberFormatException nfe)
{
// Good practice to log this, but the default int is fine.
}
Some Best Practices
Do not catch exceptions unless the compiler forces you to.
If you are catching a checked exception, then log it. You can also wrap it in a RuntimeException if you want it to percolate up the call stack.
If you want to catch a RuntimeException, then do so with a purpose (i.e. you can set a default and prevent the error all together.)
Don't have a chain of methods all throwing a checked Exception up the stack trace. This is very messing and forces all calling methods to either catch or throw the checked exception.
Catching a RuntimeException just to log it really doesn't have much of a purpose. Unless you are logging it in a catch all location.
Catch-All Example:
try
{
// entry point to application
}
catch (Throwable t)
{
// let all exceptions come here to log them
}
I am encountering an error when user doesn't type anything into input statement. I thought of using Try/Catch blocks to instead throw exception to set boolAskRepeat to true which should skip to the end of the code and repeat the loop.
This doesn't work, and I believe I'm missing something but I'm not sure what... It still throws exception saying:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 0
at java.lang.String.charAt(Unknown Source)
at ITSLab03.main(ITSLab03.java:34)
Which is this line of code: inputStatus = input.readLine().toLowerCase().charAt(0);
What am I doing wrong here?
while (boolAskStatus == true)
{
System.out.print("Employment Status (F or P): ");
try
{
inputStatus = input.readLine().toLowerCase().charAt(0);
if (inputStatus == "f".charAt(0))
{
boolAskStatus = false;
String stringCheckSalary = null;
boolean boolCheckSalary = true;
while (boolCheckSalary == true)
{
// some code
}
outputData(inputName, inputStatus, calculateFullTimePay(inputSalary));
}
else if (inputStatus == "p".charAt(0))
{
// some code
outputData(inputName, inputStatus, calculatePartTimePay(inputRate, inputHours));
}
else boolAskStatus = true;
}
catch (IOException e) { boolAskStatus = true; }
}
You need to catch StringIndexOutOfBoundsException as well (If you observe the stack trace properly this is the exception you are getting)
catch (StringIndexOutOfBoundsException e) {
boolAskStatus = true;
}
(or)
catch Exception which catches all runtime exceptions
catch (Exception e) {
boolAskStatus = true;
}
The normal try catch pattern should look like this:
try
{
// code that is vulnerable to crash
}
catch (Specific-Exception1 e1)
{
// perform action pertaining to this exception
}
catch (Specific-Exception2 e2)
{
// perform action pertaining to this exception
}
....
....
catch (Exception exp) // general exception, all exceptions will be caught
{
// Handle general exceptions. Normally i would end the program or
// inform the user that something unexpected occurred.
}
By using .charAt(0), you are assuming that the String has a length > 0.
You could simplify this a bunch by just doing:
String entry = input.readLine().toLowerCase();
if (entry.startsWith("f")) {
...
}
else if ("entry".startsWith("p")) {
...
}
Your code doesn't work the way you want because input.readLine().toLowerCase().charAt(0) throws a StringIndexOutOfBoundsException, which is not an IOException, so the catch block never gets hit. You can make it work by changing the catch to
catch (StringIndexOutOfBoundsExceptione e) { boolAskStatus = true; }
But...
It's generally not a good idea to base your program's normal behaviour on exception handling. Think of exception throwing as something that could happen, but usually won't. Why not use something like:
final String STATUS_F = "f";
final String STATUS_P = "p";
String fromUser = null;
do {
String rawInput = input.readLine().toLowerCase();
if (rawInput.startsWith(STATUS_F)) {
fromUser = STATUS_F;
} else if (rawInput.startsWith(STATUS_P)) {
fromUser = STATUS_P;
}
} while (fromUser == null);
if (STATUS_F.equals(fromUser)) {
// do something
} else if (STATUS_P.equals(fromUser)) {
// do something else
} else {
// Shouldn't be able to get here!
throw new Exception("WTF!?");
}
It much easier for another person reading this to understand why the program loops and how the loop is controlled, in part because the code that figures out what the user is inputting and the code that decides what to do with that information are separated. Plus, you don't need to deal with exceptions.
Let's say I can a set of statements:
try {
String a = getProperty("a");
String b = getProperty("b");
String c = getProperty("c");
} catch(Exception e) {
}
Now, lets say property b was not found and the function throws an exception. In this case, how would I just continue or perhaps set b to null without having to write a try-catch block for each property? I mean, a,b,c exist but sometime they might not be found at all during which an exception is thrown.
Assuming you can't change the function so that it returns null when the property isn't found, you are kind of stuck wrapping everything in its own try catch block -- especially if you want for every value that can be retrieved to be retrieved (as opposed to letting the first value that fails cancel the whole operation.)
If you have a lot of these properties to retrieve, perhaps it would be cleaner to write a helper method to use:
String getPropertySafely(String key) {
try {
return getProperty(key);
} catch (Exception e) {
return null;
}
}
You have to put a try-catch around each statement. There is no continue (like there is in ON ERROR ... RESUME blocks in VB). Instead of:
String a = null;
try {
a = getProperty("a");
} catch(Exception e) {
...
}
String b = null;
try {
b = getProperty("b");
} catch(Exception e) {
...
}
String c = null;
try {
c = getProperty("c");
} catch(Exception e) {
...
}
you could write:
public String getPropertyNoException(String name) {
try {
return getProperty(name);
} catch (Exception e) {
return null;
}
}
Personally I think a getProperty() is a poor candidate for throwing exceptions just for all this extra boilerplate required
Since you are using the same function each time you might be able to put this in a loop:
String[] abc = new String[3];
String[] param = {"a", "b", "c"};
for (int i = 0; i < 3; i++) {
try {
abc[i] = getProperty(param[i]);
} catch(Exception e) {
}
}
but this is rather contrived and would only be useful for a large number of properties. I suspect you will have to simple write 3 try-catch.
You should reconsider how getProperty is handled if you plan to use many of them because there isn't a plain way to do it.
You can exploit finally statement but you still need a try-catch for every call.