In RCML, it is available to handle exceptions occurring in a particular block of code, as in some other programming languages. General type of exception handling structure begins with try operator, then it is followed by a block of operators, where an exception can occur in execution of the operators of this block, then it can be followed by catch operator, and a block of operators to be executed in case of an exception. General type of exception handling structure is as follows:

try {
	//block of operators, where an exception can occur
} catch {
	//block of operators to handle the case with an exception
}

When an exception appears in try block, the program goes to catch block operator. It should be noted that catch operator and its block may be omitted, and then the program goes to the operator following the block of try operator. Exception handling structure may be nested in another one, and, in case of an exception, it will be handled by the current structure.

Exceptions may occur when executing various functions provided by external or system RCML modules, such as function modules or robot modules, but an exception can be called manually using throw operator. When executing this operator, an exception will immediately be thrown.

Work of the mechanism of exceptions as an example of a simple program for division of numbers:

function main() {
	try {
		echo(“this simple division program\n”);
		echo(“c = a / b \n”);
		try {
			echo(“input a\n”);
			a = input();
			echo(“input b\n”);
			b = input();
			if (!b) { // if b is zero, division cannot be executed
				throw; //throw an exception
			}
			c = a / b;
			echo(“c = ”, c, “\n”);
		} catch {
			echo(“b is zero!”); //exception will be handled in this block
		}
	} catch {
		//this block will never be executed
	}
}

However, in RCML, focused on robotics, unlike other programming languages, try operator can have parameters that specify exactly how it should work. The first parameter of try operator is a string constant specifying the mode of operation. The second parameter of real data type may be given depending on the specified mode.

Try operator has three modes of operation:

  • “error_default” – default mode of operation as a common try operator. In this case, the second parameter is not specified. If the parameters of try operator are omitted as in the above example, then try operator operates in this mode.
  • “error_time_limit” – mode of operation with a countdown of time limit in which a block of code of try operator should be executed. In this case, the second parameter is given to specify the number of milliseconds limiting execution of the block of code of try operator. If this block is not executed within the specified time, an exception will be thrown. If an exception is thrown earlier, the countdown will be stopped, and the exception will be handled normally.
  • “error_try_count” – mode of operation with a count of the number of attempts to execute the block of try operator. In this mode, the second parameter takes a number of allowed attempts to execute the block. In each thrown exception, the count of the number of attempts in try operator block will be reduced by 1, and if it reaches zero, the exception will be handled normally.

Despite the fact that try operator may take the parameters, it is not a function and does not returns a value.

Example of using the above modes to handle success of robot performance of its function giving it three attempts with a time limit of 2 seconds for each:

try(“error_try_count”, 3) {
	try(“error_time_limit”, 2000) {
		robot->do_something();
	} catch { //if time is out
		throw; //then throw an exception to end the attempt
	}
} catch {
	//this block is executed when all attempts are ended 
	//with no result obtained
}

Using the throw operator, the exception may be used for passing some value (exception value). In this case, the syntax of the throw operator will be the following:

throw expression;

For processing the value of the thrown exception, the try operator will have a slightly different syntax: the parameters of the catch operator should specify the identifier, i.e., the name of the variable to which the exception will be written:

try {
	//the block of operators in which the exception may occur
} catch (variable_name) {
	//the block of operators for handling an exception
}

If at the time of exception the specified variable does not exist, it will be created, otherwise it will be overwritten.

try {
	throw 3;
} catch (E) {
	system.echo(“E = ”, E, “\n”); //will show E = 3
}

The variable, to which the value of the exception will be written, will be available in the catch block and beyond it till the end of the function.

An example of creating the variable:

system.echo(“E = ”, E, “\n”); //error E does not exist yet
try {
	throw 3;
} catch (E) {
	system.echo(“E = ”, E, “\n”); //will show E = 3
}
system.echo(“E = ”, E, “\n”); //will show E = 3, since E has been created in the catch block

An example of overwriting the value:

E = 5;
system.echo(“E = ”, E, “\n”); //will show E = 5
try {
	throw 3;
} catch (E) {
	system.echo(“E = ”, E, “\n”); //will show E = 3
}
system.echo(“E = ”, E, “\n”); //will show E = 3

In this way it is possible not only to process exception values passed via the throw operator, but also to process exception values passed from functions of robot modules and functional modules, and libraries.

Example:

try {
	robot_test->throw_value(10);
} catch (E) {
	system.echo(“E = ”, E, “\n”); //will show E = 10
}

If the thrown exception has not been intercepted in the RCML program, the RCML program will terminate with code 1, i.e., an error, which may be a communication tool between the OS and the RCML program (read more in Section "Communication with the OS"). In this case, the value of the exception will be lost.