Handling known exceptions
Exceptions are unexpected events that disrupt a bot's runtime. Although unexpected, the developer can predict these events. This section describes how to handle known exceptions in your IBM RPA script.
You can handle known exceptions by:
- Handling the exception event with the Handle Error (
onError
) command. - Using flow control conditional commands for validation.
For example, consider the following script: unhandled_division
. You can copy the following script and paste it in the Script tab of IBM RPA Studio.
defVar --name text_dividend --type String
defVar --name text_divisor --type String
defVar --name num_dividend --type Numeric
defVar --name num_divisor --type Numeric
defVar --name quotient --type Numeric
// Prompt user for dividend and divisor.
// Perform division of dividend by divisor and show quotient.
inputBox --title "The dividend" --prompt "Enter the dividend" text_dividend=value
convertStringToNumber --text "${text_dividend}" --allowleadingsign --allowdecimalpoint --allowthousands num_dividend=value
inputBox --title "The divisor" --prompt "Enter the divisor" text_divisor=value
convertStringToNumber --text "${text_divisor}" --allowleadingsign --allowdecimalpoint --allowthousands num_divisor=value
evaluate --expression "${num_dividend} / ${num_divisor}" quotient=value
messageBox --title "The quotient" --text "${num_dividend} / ${num_divisor} = ${quotient}" --icon "Information" --buttons "OK" --defaultbutton "FirstButton"
The unhandled_division
script relies on user input to perform a division and show the result. Relying on raw user input can become troublesome if the bot doesn't validate the input.
The Convert Text to Number (convertStringToNumber
) command converts a text variable into a number variable. The command assumes the text variable has the expected
pattern, which needs to be a number. However, the Input Box (inputBox
) command accepts any text input from the user. In unhandled_division
, a runtime
exception will happen if the user enters anything other than a number in the input dialog window.
We can classify the event of entering the wrong input as a known exception since it disrupts the bot's runtime, but we can handle it properly. You could handle this exception by:
- Catching the exception
- Validating the user input
Handling the exception
In the unhandled_division
script, you could handle the exception like in the following script:
defVar --name text_dividend --type String
defVar --name text_divisor --type String
defVar --name num_dividend --type Numeric
defVar --name num_divisor --type Numeric
defVar --name quotient --type Numeric
defVar --name dividend_acquired --type Boolean
defVar --name divisor_acquired --type Boolean
// Perform division of dividend by divisor and show quotient.
goSub --label get_user_input_for_dividend
goSub --label get_user_input_for_divisor
goSub --label evaluate
messageBox --title "The quotient" --text "${num_dividend} / ${num_divisor} = ${quotient}" --icon "Information" --buttons "OK" --defaultbutton "FirstButton"
beginSub --name get_user_input_for_dividend
// Prompts user for dividend input until acquired successfuly or user aborts.
while --left "${dividend_acquired}" --operator "Is_True" --negate
inputBox --title "The dividend" --prompt "Enter the dividend (type abort to stop the bot)" text_dividend=value
setVar --name "${dividend_acquired}" --value True
onError --label get_user_input_for_dividend_exception_handler
convertStringToNumber --text "${text_dividend}" --allowleadingsign --allowdecimalpoint --allowthousands num_dividend=value
endWhile
endSub
beginSub --name get_user_input_for_divisor
// Prompts user for divisor input until acquired successfuly or user aborts.
while --left "${divisor_acquired}" --operator "Is_True" --negate
inputBox --title "The divisor" --prompt "Enter the divisor (type abort to stop the bot)" text_divisor=value
setVar --name "${divisor_acquired}" --value True
onError --label get_user_input_for_divisor_exception_handler
convertStringToNumber --text "${text_divisor}" --allowleadingsign --allowdecimalpoint --allowthousands num_divisor=value
endWhile
endSub
beginSub --name get_user_input_for_dividend_exception_handler
// Exception handler subroutine for the get_user_input_for_dividend subroutine.
// Abort if user requests or warn user about invalid input.
if --left "${text_dividend}" --operator "Matches" --right "(?i)^abort"
logMessage --message "User wants to abort." --type "Info"
stopExecution --current
else
messageBox --title "Invalid input" --text "Please, enter a valid number!" --icon "Error" --buttons "OK" --defaultbutton "FirstButton"
setVar --name "${dividend_acquired}" --value False
recover
endIf
endSub
beginSub --name get_user_input_for_divisor_exception_handler
// Exception handler subroutine for the get_user_input_for_divisor subroutine.
// Abort if user requests or warn user about invalid input.
if --left "${text_divisor}" --operator "Matches" --right "(?i)^abort"
logMessage --message "User wants to abort." --type "Info"
stopExecution --current
else
messageBox --title "Invalid input" --text "Please, enter a valid number!" --icon "Error" --buttons "OK" --defaultbutton "FirstButton"
setVar --name "${divisor_acquired}" --value False
recover
endIf
endSub
beginSub --name evaluate
// Evaluate division. onError watches for unexpected behaviour.
onError --label evaluate_exception_handler
evaluate --expression "${num_dividend} / ${num_divisor}" quotient=value
endSub
beginSub --name evaluate_exception_handler
// Display error message and stop.
messageBox --title "Division went wrong!" --text "${wdg:error.Message}" --icon "Error" --buttons "OK" --defaultbutton "FirstButton"
stopExecution --current
endSub
You can use Handle Error (onError
) on specific subroutines to handle known errors within that scope. Another possibility is to validate the user input:
defVar --name text_dividend --type String
defVar --name text_divisor --type String
defVar --name num_dividend --type Numeric
defVar --name num_divisor --type Numeric
defVar --name quotient --type Numeric
defVar --name valid_input --type Boolean
defVar --name user_input --type String
// Perform division of dividend by divisor and show quotient.
goSub --label get_user_input_for_dividend
goSub --label get_user_input_for_divisor
evaluate --expression "${num_dividend} / ${num_divisor}" quotient=value
messageBox --title "The quotient" --text "${num_dividend} / ${num_divisor} = ${quotient}" --icon "Information" --buttons "OK" --defaultbutton "FirstButton"
beginSub --name get_user_input_for_dividend
// Prompt user for dividend until valid input or user wants to abort.
setVar --name "${valid_input}" --value False
while --left "${valid_input}" --operator "Is_True" --negate
inputBox --title "The dividend" --prompt "Enter the dividend (use . for decimals). This ignores commas. Type abort to end bot." text_dividend=value
replaceText --texttoparse "${text_dividend}" --textpattern "," text_dividend=value
if --left "${text_dividend}" --operator "Matches" --right "(?i)^abort"
goSub --label abort_execution
else
goSub --label validate_user_input --assignments "${user_input}=${text_dividend}"
gosubIf --label warn_invalid_input --left "${valid_input}" --operator "Is_True" --negate
endIf
endWhile
convertStringToNumber --text "${text_dividend}" --allowleadingsign --allowdecimalpoint --allowthousands num_dividend=value
endSub
beginSub --name get_user_input_for_divisor
// Prompt user for divisor until valid input or user wants to abort.
setVar --name "${valid_input}" --value False
while --left "${valid_input}" --operator "Is_True" --negate
inputBox --title "The divisor" --prompt "Enter the divisor (use . for decimals). This ignores commas. Type abort to end bot." text_divisor=value
replaceText --texttoparse "${text_divisor}" --textpattern "," text_divisor=value
if --left "${text_divisor}" --operator "Matches" --right "(?i)^abort"
goSub --label abort_execution
else
goSub --label validate_user_input --assignments "${user_input}=${text_divisor}"
gosubIf --label warn_invalid_input --left "${valid_input}" --operator "Is_True" --negate
endIf
endWhile
convertStringToNumber --text "${text_divisor}" --allowleadingsign --allowdecimalpoint --allowthousands num_divisor=value
if --left "${num_divisor}" --operator "Equal_To" --right 0
// Handle when divisor is 0.
messageBox --title "Invalid input" --text "Divisor can/'t be 0." --icon "Warning" --buttons "OK" --defaultbutton "FirstButton"
goSub --label get_user_input_for_divisor
endIf
endSub
beginSub --name validate_user_input
// Validade user input.
// User input must be a valid number with decimals separated by point.
replaceText --texttoparse "${user_input}" --textpattern "," user_input=value
isMatch --text "${user_input}" --regexPattern "^//d+(?:.?//d+)?$" --regexOptions "0" valid_input=value
endSub
beginSub --name abort_execution
// Log and abort execution.
logMessage --message "User wants to abort." --type "Info"
stopExecution --current
endSub
beginSub --name warn_invalid_input
// Warn when input is invalid.
messageBox --title "Invalid input" --text "Please, enter a valid number (use . for decimals)." --icon "Warning" --buttons "OK" --defaultbutton "FirstButton"
endSub
You can validate known exceptions with flow control conditionals. This type of validation makes it easier for you to create specific exception handling logic, but it can make the script grow in size if there are many possible exception events.
The success
output parameter
Some commands in IBM Robotic Process Automation have an output parameter called success
. This output parameter returns a boolean representing the command's success in doing its task. You can validate this output parameter to handle
known exception events in your script by creating alternative conditional flows.