Another one of the features in http://groups.drupal.org/project/provision, is an extensible api that hooks into error handling and logging.
Essentially, when defining you command in drush_commands, you specify :
$cmd['my command'] = array( 'callback' => 'drush_invoke', 'callback arguments' => array('mycommand'), );
By doing this, you automatically have access to the following hooks:
$hook_drush_mycommand_validate() : which allows you to check for the valid input.
$hook_drush_pre_mycommand() : Do initial setup for your command.
$hook_drush_command() : Do the actual work required.
$hook_drush_post_command() : Finalize and clean up after yourself.
Now the beauty of this is, is that not just your module, but any module have access to these hooks.
We use it in provision to separate concerns, so when provisioning a new site, the pre_command of the
mysql sets up the database, for the rest of the process to happen. We could add additional modules
(such as dns hosting), which can interact with these commands.
Additionally, if at any point a drush_set_error is called, it will automatically stop recurring through the hooks,
and run through the options it tried in reverse, but adding rollback to the command, such as :
Allowing you to back out problems you have created for yourself.
What is also useful in this, is that it allows the commands that use this api to call each other.
Say for instance you are doing a site upgrade, and you need to back up before you run the update,
you can just do 'drush_invoke("backup")'.
The mechanism that we communicate between the hooks, is we pass a context reference through all the functions
we call, so when the mysql_pre_install hook has created the database, it sets the mysql_user and mysql_password
in the context array, and passes it to the other modules that need to create the configuration files and the like.
A couple of notes: In provision we have 2 extra hooks, for all modules (which would need to be integrated into drush
more directly), namely 'provision_init' and 'provision_finalize'. Because we don't have the drupal init hooks available,
we tend to use these, and they work pretty well for us.
In provision, we doing just look for *.drush.inc files, but we auto-load these additional crosscuts dynamically from all
modules we find them.
An example of such a file is here : http://drupalbin.com/4343
Simply by creating the filename with the name : disable.provision.inc, in the provision_drupal.module directory, it will get loaded automatically, making it incredibly easy to extend any command on the system.
This code is a bit more complex to un-provision-i-fy, but these are the basic requirements for this patch to land, it uses all of these,
so it's impossible to create a modular patch without them :