Skip to content

Insulin Exception

jcsmorais edited this page Jul 2, 2012 · 7 revisions

#Insulin Exception

The Insulin_Exception is the base exception from which all others extend. It allows you to easily create and throw new exceptions, create easily recognisable and unique error codes, to configure multi-language exception messages, add previous exceptions and also has a custom method which creates a pretty-printable log-message string.

#How to

So, lets get hands on.

To create a new exception for a custom module MyModule, create the following file on modules/MyModule/exceptions/Exception.php:

<?php

require_once 'Insulin/Exception.php';

class MyModule_Exception extends Insulin_Exception
{
}

Note that, according to the Insulin standards, a base exception should be created for MyModule, as done above. Furthermore, these standards also define that all custom modules' exceptions should be placed under the modules/MyModule/exceptions folder. As for core module customizations, the exceptions should be in custom/modules/<CoreModule>/exceptions folder instead.

If, by instance, one needs to throw an exception when a record isn't found, the first thing to do is the creation of the module's base exception (which extends from Insulin_Exception), in other words, the exception from which all modules' exceptions will extend from. After that, a specific exception should be created for the issue in question, in this case, the exception could be named IdNotFoundException where it would receive the record id related to the registry that wasn't found, in order for us to have a more meaningful exception message while debugging.

On to creating the new exception inside modules/MyModule/exceptions/IdNotFoundException.php file:

<?php

require_once 'modules/MyModule/exceptions/Exception.php';

class MyModule_IdNotFoundException extends MyModule_Exception
{
    public function __construct($id)
    {
        parent::__construct(array($id));
    }
}

Now, you might be asking your self, why are we only passing the id?

In the Insulin_Exception, the first argument of the constructor is an array with all the variables needed to have a more meaningful exception message; in the second argument, the previous exception (optional), that allows traceability between exceptions and an easier understanding of the origin of the exception caught.

And what about the error message?

The Insulin_Exception, uses the SugarCRM label mechanism to provide multi-language support for its error messages. Error messages are searched for in the $mod_strings and $app_strings. The labels defined in the $mod_strings override the ones in the $app_strings. If the $app_strings are used, the Insulin standards define that the exception messages should be placed in <language_code>.<module_name>.php under the custom/Extension/application/Ext/Language folder. If, by instance, both English and Portuguese languages are supported, add the messages to:

  • en_us.MyModule.php
  • pt_PT.MyModule.php

What about the error code? Also, what key should be used to add the error message to the languages array?

For the Insulin_Exception these are the same, the exceptions error code should be used as a key of the array entry. The exceptions error code are automatically defined based on the exception class name. It is a string composed of uppercase words separated by underscores _. The keys are composed by separating with underscores the CamelCase words from the exception class name and then place all the text in uppercase. Thus, for the MyModule_IdNotFoundException you will get the code MY_MODULE_ID_NOT_FOUND_EXCEPTION.

Note that, exceptions with an uppercase letter followed by another uppercase letter, should not be separated by an underscore in the exception code, e.g, for a work orders module, named WO, in a IdNotFoundException it would get WO_ID_NOT_FOUND_EXCEPTION. But, if you have a module that starts with a lower case letter and is followed by an upper case letter/word, the exception code should have the the lower case letter separated by an _, therefore in an iPortal module you would get I_PORTAL_ID_NOT_FOUND_EXCEPTION.

Here is a code sample:

$app_strings['MY_MODULE_ID_NOT_FOUND_EXCEPTION'] = "Could not find the record.";

The variables defined in the array passed as first argument of the class constructor, can be added to the exception's message by placing a token like %1\$s (same as used in the php sprintf function), where the number is the position of the variable in the array. Knowing this, we can define a more precise and informative error message and the arguments can be used in any order:

$app_strings['MY_MODULE_ID_NOT_FOUND_EXCEPTION'] = "Could not find the record with id '%1\$s'.";

Can I instantiate the Insulin_Exception directly?

Its not a good practice to do so, and it should only be done for developer "coding" exceptions. Nonetheless, it is possible. For this, the error message should not be defined in the $app_strings, but pass it as the first entry of the arguments array. Like so:

require_once 'Insulin/Exception.php';
throw new Insulin_Exception(array(
    'Some Insulin_Exception error message.'
));
Clone this wiki locally