Exception Handling for Custom Keywords

Hi,

I have created a custom keyword where, if the validation fails, I throw an exception.

I am calling that Custom Keyword in my Test Case that is surrounded in a Try…Catch block.

The Exception thrown in the Custom Keyword is not caught in the Test Case’s catch block.

Could not post the original script but, below is a sample with the same control flow

public class CheckException {
@Keyword
def chkEx(){
boolean check = true
if (check == false){
throw new Exception(“Boolean is fasle”)
}
}
}

-------------------------------Test Case-------------------------------

try{

   CustomKeywords.'CheckException.chkEx'  

} catch (Exception e){
e.getMessage()
}

Please let me know how to catch the exception in the main test case?

Perhaps the problem is caused by how Katalon handles the exception stack?

This works fine in my Keyword classes – however, I don’t use @Keyword, instead I create static methods, like this:

import com.kms.katalon.core.exception.StepErrorException as StepErrorException


public class mytools {

  static void chkBoolean(boolean chk) {
    if(!chk) {
      throw new StepErrorException("Boolean chk is false")
    }
  }

  static void otherMethod() { ... }
}

And in my Test Case, I call them like this:

import static mytools.*

try {
   chkBoolean(whatever)
} catch (Exception e) {
  // do stuff with e
  // maybe throw e again
}

In fact, my whole test is contained in a Test class constructor called Test:

// imports ...

public class Test extends page_from_my_pom {
  Test() {
    navigateTo() // go to page_from_pom

    // more steps here
  }
}

try {
  new Test()
  passThisTest() // static method
} catch (Exception e) {
  failThisTest(e.message) // static method 
  throw e
}

It’s a nice enough model giving me pretty good control (before handing control back to Katalon) – I hope it helps you.

4 Likes

@Russ Thomas

This works great. Exactly what I was looking for.

Thanks a lot!!!

You’re very welcome. And thanks for the BA B)

@Russ Thomas
Why is it that when I print the exception as it is, it prints the complete stack trace information without any issues.
But, when I use e.getMessage() or e.Message(), it prints null

I use e.message

@Russ Thomas
e.message doesn’t work as well. It prints null

Show me your try-catch block.

It is working now. I had created a User Defined Exception and was trying to call the e.message instead of converting the exception to string.
Works now with e.toString().

Using `StepErrorException` inside CustomKeyword also works. Throwing any exection works so `throw new Exception(“some message”)` will also work and doesn’t seem to be much of a difference to Katalon.

So this is something I came up with to handle errors in a custom keyword. But Katalon seems to be actually handling failures differently so YMMV…

@Keyword
String waitUntilVisible(String componentSelector, int timeout = 10, FailureHandling failureHandling = FailureHandling.STOP_ON_FAILURE) {
		KeywordLogger log = new KeywordLogger();
//...
		if (id == null || id.isEmpty()) {
			String message = "Component was not found within ${timeout}s (using query '${componentSelector}')";
			if (failureHandling == FailureHandling.STOP_ON_FAILURE) {
				throw new StepErrorException(message);
			} else if (failureHandling == FailureHandling.CONTINUE_ON_FAILURE) {
				log.logError(message);
			} else {
				log.logWarning(message);
			}
		}
		return id;
}

Hi
I’m encountering StepErrorException even I already marked it as passed.
Here’s my code.

public def Boolean isElementPresent(String xpath) {
try {
this.wait = new WebDriverWait(this.driver, 10);
WebElement element = this.driver.findElement(By.xpath(xpath));
return true;
}
catch(org.openqa.selenium.NoSuchElementException ex) {
return false
}
catch(Exception ex) {
return false;
}
}

It already passed when I marked it as Passed but it returns an error
2020-02-17 17:17:40.735 ERROR k.k.c.m.CustomKeywordDelegatingMetaClass - :x: com.kms.katalon.core.exception.StepErrorException: Expected condition failed: waiting for presence of element located by: By.xpath: //app-iic-reviews//div[contains(@class,‘card border rounded’)] (tried for 10 second(s) with 500 milliseconds interval)