Table of Contents
Enroll in Selenium Training

What is an Exception

An Exception is an event, which occurs during the execution of a program, that disrupts the normal flow of the program’s instructions or in simple words, any issue which makes your test case stop in between the execution is an Exception.

Difference between Error and Exception

An Error “indicates serious problems that a reasonable application should not try to catch”.

An Exception “indicates conditions that a reasonable application might want to catch”.

Whenever an error occurs while executing a statement, creates an exception object and then the normal flow of the program halts and it tries to find someone that can handle the raised exception. The exception object contains a lot of debugging information such as method hierarchy, line number where the exception occurred, type of exception etc. When the exception occurs in a method, the process of creating the exception object and handing it over to runtime environment is called “throwing the exception”.

What is Exception Handling

Exception handling refers to the anticipation, detection, and resolution of programming application, and communications errors. It is the block of code that processes the exception object and helps us by giving us a chance to act on it.

Why Exception Handling is Important

  1. Think of a situation where you have got an exception and you want to print some custom message in your  logs, so that it can be understandable by the whole team.

  2. There can be some situations where you want to just eat up the exception and want your test to carry on with rest of the execution.

  3. In case you want to perform some series of steps on occurring of an certain exception for e.g. if you got an exception because a product is out of stock, that product is no longer displayed on the page and you want you to go with another product available on the page.

  4. In case you want to handle some certain kind of exception in Selenium like ElementNotSelectableException, ElementNotVisibleException, NoSuchElementException etc. exceptions.

Different Exceptions in Selenium

There is a complete list of Exceptions mentioned on the Selenium Doc which you may or may not encounter in course of your  testing.

Most common Exceptions:

  1. NoSuchElementException: FindBy method can’t find the element.
  2. StaleElementReferenceException: This tells that element is no longer appearing on the DOM page.
  3. TimeoutException: This tells that the execution is failed because the command did not complete in enough time.
  4. ElementNotVisibleException: Thrown to indicate that although an element is present on the DOM, it is not visible, and so is not able to be interacted with
  5. ElementNotSelectableException: Thrown to indicate that may be the element is disabled, and so is not able to select.

How to Handle Exception

Try/Catch: A method catches an exception using a combination of the try and catch keywords.Try is the start of the block and Catch is at the end of try block to handle the exceptions. A try/catch block is placed around the code that might generate an exception. Code within a try/catch block is referred to as protected code, and the syntax for using try/catch looks like the following:

try{
    // Some code
}catch(Exception e){
    // Code for Handling the exception
    }

Multiple Catch blocks: A try block can be followed by multiple catch blocks. Like I said earlier, that there are multiple exceptions and you can expect more than one type of exception on a single code block and if you like to handle each type of exception separately with a separate block of code. The syntax for multiple catch blocks looks like the following:

try{
    //Some code
}catch(ExceptionType1 e1){
    //Code for Handling the Exception 1
}catch(ExceptionType2 e2){
    //Code for Handling the Exception 2
   }

There is no restriction on the number of the catch blocks, you can use more than two. You may be wondering that how does it work. It is pretty simple, if an exception occurs in the protected code, the exception is thrown to the first catch block in the list. If the exception thrown matches the ExceptionType1, it gets caught there and it executes the code which is under the same exception block. If not, the exception passes down to the second catch statement and goes on like this.

Note: In case the exception does not match with any exception type and falls through all catches, the current method stops execution and exception is thrown. That is why it is advisable to include default exception as well in the end, so in case if the exception falls through, it can be handled by the default one.

Throw: Sometimes we want to generate exception explicitly in our code, for example in Selenium Automation Framework most of the time we print self-written logs, once we catch an exception and then we need to throw that exception back to the system so that the test case can be terminated. Throw keyword is used to throw exception to the run time to handle it.

Throws: When we are throwing any exception in a method and not handling it, then we need to use throws keyword in method signature to let caller program know the exceptions that might be thrown by the method.

// Method Signature\
public static void anyFunction() throws Exception{
    try{
        // write your code here    
    }catch (Exception e){
        // Do whatever you wish to do here
        // Now throw the exception back to the system
        throw(e);
        }
    }

Multiple Exceptions: Multiple exceptions can be handled in the throws clause.

public static void anyFunction() throws ExceptionType1, ExceptionType2{
    try{
         //Some code 
     }catch(ExceptionType1 e1){ 
         //Code for Handling the Exception 1
     }catch(ExceptionType2 e2){
         //Code for Handling the Exception 2
     }

Finally: The finally keyword is used to create a block of code that follows a try block. A finally block of code always executes, whether or not an exception has occurred.

try{
    //Protected code
}catch(ExceptionType1 e1){
    //Catch block
}catch(ExceptionType2 e2){
    //Catch block
}catch(ExceptionType3 e3){
    //Catch block
}finally{
    //The finally block always executes.
    }

Exception Handling in Framework

Your Selenium test should be able to fail, but not because of exceptions that are thrown. If your test is failing from exceptions then quite likely you have no exception handling. By doing this, you don’t have the opportunity to cleanup the WebDriver object at the end of the test.

The tests should be failing under your terms only for example, you should never be getting exceptions like NullPointerException but if you are getting such as ElementNotFoundException, then also it is good idea to catch the exception, stop the further execution and end your test in a Logical way.

As I stated above that when ever we face any exception, it is better to print logs of the error, so that it can be investigated. Throwing error depends on framework to framework because if you catch the exception and throw the exception back to the main program, it is necessary to have an try catch block in the main program as well, so that test case can be closed in a proper manner. If you do not handle the exception, the test case will stop right there and it will not execute the other test cases of batch run.

Exception Handling in this Framework

As I said it completely depends on you how you want to handle the exception, so it is not necessary to follow this approach. You can do it on your own way. I create a 'public static boolean bResult;' variable in my main driver script and I set its value to 'true' at starting of each test case and each test step. Means we have two loops in the main driver script, outer loop is for test cases and inner loop is for test steps. So on start of every new test case and test step, I set this variable value to 'true'. The idea behind it to change the value from 'true' to 'false' at the time of any exception. The exception will be caught with the try catch block and the statement to change the value from 'true' to 'false' will reside in that block. For example:

public static void openBrowser(String object){
	try{
	Log.info("Opening Browser");
	driver=new FirefoxDriver();
	}catch(Exception e){
		Log.info("Not able to open Browser --- " + e.getMessage());
		DriverScript.bResult = false;
		}
	}

It means the bResult value will set to 'false' only in case of an exception, other wise it will always remain 'true'. So now we just need to match the value of bResult in the main driver script. If it is true, execute the next step and if it is false, stop the test step and test case and move forward to next test case.

The ActionKeyword class and ExcelUtils class will look like this, once the exception handling is set up in the framework:

Action Keyword Class

package config;

import java.util.concurrent.TimeUnit;
import static executionEngine.DriverScript.OR;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import executionEngine.DriverScript;
import utility.Log;

public class ActionKeywords {

		public static WebDriver driver;

	public static void openBrowser(String object){
		try{
		Log.info("Opening Browser");
		driver=new FirefoxDriver();
		
		//This block will execute only in case of an exception
		}catch(Exception e){
			//This is to print the logs - Method Name & Error description/stack
			Log.info("Not able to open Browser --- " + e.getMessage());
			//Set the value of result variable to false
			DriverScript.bResult = false;
			}
		}

	public static void navigate(String object){
		try{
			Log.info("Navigating to URL");
			driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
			driver.get(Constants.URL);
		}catch(Exception e){
			Log.info("Not able to navigate --- " + e.getMessage());
			DriverScript.bResult = false;
			}
		}

	public static void click(String object){
		try{
			Log.info("Clicking on Webelement "+ object);
			driver.findElement(By.xpath(OR.getProperty(object))).click();
		 }catch(Exception e){
 			Log.error("Not able to click --- " + e.getMessage());
 			DriverScript.bResult = false;
         	}
		}

	public static void input_UserName(String object){
		try{
			Log.info("Entering the text in UserName");
			driver.findElement(By.xpath(OR.getProperty(object))).sendKeys(Constants.UserName);
		 }catch(Exception e){
			 Log.error("Not able to Enter UserName --- " + e.getMessage());
			 DriverScript.bResult = false;
		 	}
		}

	public static void input_Password(String object){
		try{
			Log.info("Entering the text in Password");
			driver.findElement(By.xpath(OR.getProperty(object))).sendKeys(Constants.Password);
		 }catch(Exception e){
			 Log.error("Not able to Enter Password --- " + e.getMessage());
			 DriverScript.bResult = false;
		 	}
		}

	public static void waitFor(String object) throws Exception{
		try{
			Log.info("Wait for 5 seconds");
			Thread.sleep(5000);
		 }catch(Exception e){
			 Log.error("Not able to Wait --- " + e.getMessage());
			 DriverScript.bResult = false;
         	}
		}

	public static void closeBrowser(String object){
		try{
			Log.info("Closing the browser");
			driver.quit();
		 }catch(Exception e){
			 Log.error("Not able to Close the Browser --- " + e.getMessage());
			 DriverScript.bResult = false;
         	}
		}

	}

Excel Utils Class:

package utility;

import java.io.FileInputStream;
import java.io.FileOutputStream;

import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFRow;

import config.Constants;
import executionEngine.DriverScript;
    public class ExcelUtils {
			private static XSSFSheet ExcelWSheet;
			private static XSSFWorkbook ExcelWBook;
			private static org.apache.poi.ss.usermodel.Cell Cell;
			private static XSSFRow Row;

		public static void setExcelFile(String Path) throws Exception {
			try {
				FileInputStream ExcelFile = new FileInputStream(Path);
				ExcelWBook = new XSSFWorkbook(ExcelFile);
			} catch (Exception e){
				Log.error("Class Utils | Method setExcelFile | Exception desc : "+e.getMessage());
				DriverScript.bResult = false;
				}
			}

		public static String getCellData(int RowNum, int ColNum, String SheetName ) throws Exception{
			try{
				ExcelWSheet = ExcelWBook.getSheet(SheetName);
				Cell = ExcelWSheet.getRow(RowNum).getCell(ColNum);
				String CellData = Cell.getStringCellValue();
				return CellData;
			 }catch (Exception e){
				 Log.error("Class Utils | Method getCellData | Exception desc : "+e.getMessage());
				 DriverScript.bResult = false;
				 return"";
				 }
			 }

		public static int getRowCount(String SheetName){
			int iNumber=0;
			try {
				ExcelWSheet = ExcelWBook.getSheet(SheetName);
				iNumber=ExcelWSheet.getLastRowNum()+1;
			} catch (Exception e){
				Log.error("Class Utils | Method getRowCount | Exception desc : "+e.getMessage());
				DriverScript.bResult = false;
				}
			return iNumber;
			}

		public static int getRowContains(String sTestCaseName, int colNum,String SheetName) throws Exception{
			int iRowNum=0;	
			try {
				//ExcelWSheet = ExcelWBook.getSheet(SheetName);
				int rowCount = ExcelUtils.getRowCount(SheetName);
				for (; iRowNum<rowCount; iRowNum++){
					if  (ExcelUtils.getCellData(iRowNum,colNum,SheetName).equalsIgnoreCase(sTestCaseName)){
						break;
					}
				}       			
			} catch (Exception e){
				Log.error("Class Utils | Method getRowContains | Exception desc : "+e.getMessage());
				DriverScript.bResult = false;
				}
			return iRowNum;
			}

		public static int getTestStepsCount(String SheetName, String sTestCaseID, int iTestCaseStart) throws Exception{
			try {
				for(int i=iTestCaseStart;i<=ExcelUtils.getRowCount(SheetName);i++){
					if(!sTestCaseID.equals(ExcelUtils.getCellData(i, Constants.Col_TestCaseID, SheetName))){
						int number = i;
						return number;      				
						}
					}
				ExcelWSheet = ExcelWBook.getSheet(SheetName);
				int number=ExcelWSheet.getLastRowNum()+1;
				return number;
			} catch (Exception e){
				Log.error("Class Utils | Method getRowContains | Exception desc : "+e.getMessage());
				DriverScript.bResult = false;
				return 0;
			}
		}

	}

This is all for exception handling in the framework. In the next chapter of Test Result Reporting, we will learn how to report the test case as failed when the value of bresult is 'false'.

Log4j Logging
Log4j Logging
Previous Article
Test Result Reporting
Test Result Reporting
Next Article
Lakshay Sharma
I’M LAKSHAY SHARMA AND I’M A FULL-STACK TEST AUTOMATION ENGINEER. Have passed 16 years playing with automation in mammoth projects like O2 (UK), Sprint (US), TD Bank (CA), Canadian Tire (CA), NHS (UK) & ASOS(UK). Currently, I am working with RABO Bank as a Chapter Lead QA. I am passionate about designing Automation Frameworks that follow OOPS concepts and Design patterns.
Reviewers
Virender Singh's Photo
Virender Singh

Similar Articles

Feedback