2.2. Exceptions

All error handling in eBox is implemented with java-style exceptions. These are provided by the perl module Error, you can check the perl documentation for that module for a detailed description on how to use exceptions in perl. eBox exceptions are defined in the EBox::Exceptions namespace.

eBox provides a hierarchy of exceptions from which you can choose the most appropriate for each situation. All eBox exceptions inherit from one of these two exceptions:

The difference between these two kinds is what the user will see when an uncaught exceptions occurs. The user interface framework will show the message contained in the exception unaltered if the exception is an external one. You should use external exceptions for user induced errors, like a syntax error in an IP address given by the user interface to the module backend.

If the exception is internal it will log the error and assume something is wrong internally in eBox (a bug) or in the system in general. When an internal exception is caught by the GUI framework the user will see a generic error message, recommending him to check the system logs or seek technical support. Any exception, internal or external, may be used internally for other purposes, as long as it is caught before it goes all the way up to the GUI framework.

The internal exceptions developed are:

EBox::Exceptions::Command

Exception raised when there was an error launching a command, that is, its returned value is different from zero. EBox::Exceptions::Command::Sudo does the same but with a sudo command.

EBox::Exceptions::DataInUse

Exception raised when there is a data in eBox which it is about to be removed which it is being used by another part of eBox.

EBox::Exceptions::DeprecatedMethod

Exception raised when a deprecated method has been called at runtime.

EBox::Exceptions::InvalidType

Exception raised when the type of an argument is not the expected one.

EBox::Exceptions::Lock

Exception raised when a module cannot get the lock.

EBox::Exceptions::MissingArgument

Exception raised when a compulsory argument is missing in a method call

EBox::Exceptions::NotImplemented

Exception raised when a method is not yet implemented. It could be used in an Abstract class in order to simulate its behaviour.

The external exceptions developed are:

EBox::Exceptions::DataExists

Exception raised when a user wants to add an element to eBox which already exists.

EBox::Exceptions::DataMissing

Exception raised when a user ignores a compulsory element which has to be filled to apply the configuration change.

EBox::Exceptions::DataNotFound

Exception raised when a user searches for an element which does not exist in eBox.

EBox::Exceptions::InvalidData

Exception raised when a user enters a value for a data which is invalid. An advice to the user may be set.

If you can't find an exception for certain error condition, you have two options: create a new exception class, inheriting from either EBox::Exceptions::External or EBox::Exceptions::Internal, or just use one those two classes as generic exceptions:

Example 2.3. Throwing a generic internal exception

if ($foo_condition) {
	throw EBox::Exceptions::Internal('Something happened!');
}

As you can see, throwing exceptions follows a syntax very similar to Java's. Catching them is very similar too:

Example 2.4. Catching an exception

use Error qw(:try);

sub foo
{
	my $bar = shift;

	try {
		$bar->doSomething();
	} catch EBox::Exceptions::Base with {
		# do nothing, just ignore the error
	};
}

You can do whatever you like inside the “catch” clause. You may also write several “catch” clauses if you need to do different things for different exception types. “otherwise” and “finally” clauses are also allowed, for a detailed explanation about them just run perldoc Error. A very important detail is not to forget the semicolon after the last clause (the “catch” in the example), failing to do so may produce very weird results, this is due to the black magic that is used in the implementation of the try-catch idiom.