Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Since the provision project is back end only, i need a mechanism to present errors to the front end.
To that end i've been using a simple provision_set_error() singleton pattern that uses a bitmask integer (with defines) to represent the error codes, at the end it returns the provision_get_errors() value with exit();
This is unfortunately not very useful for figuring out what goes wrong when drush is not working as it should be (a good example here would be DRUSH_DB_INACCESSIBLE_ERROR)
I have code here that does all that, but don't have the time to integrate it right now.
Comment | File | Size | Author |
---|---|---|---|
#12 | drush_errors.diff | 11.95 KB | adrian |
#10 | drush_errors.diff | 11.97 KB | adrian |
#9 | drush_errors.diff | 11.38 KB | adrian |
#7 | drush_errors.diff | 11.39 KB | adrian |
#3 | drush_errors.diff | 5.69 KB | adrian |
Comments
Comment #1
moshe weitzman CreditAttribution: moshe weitzman commentedNot sure what to do here. Need code or more description of the proposed changes.
Comment #2
adrian CreditAttribution: adrian commentedHere's what we have at the moment :
And we set up errors like :
So you just exit with exit(provision_get_error());
This obviously needs to be generalized for drush, but it is also extensible.
Comment #3
adrian CreditAttribution: adrian commentedHere is a patch for drush, that keeps the same structure as the provision code for the error handling.
It might be a bit too provision specific (for instance provision_web_error is only applicable when you are directly interacting with the web server, although could be re-used for trying to download files with wget and the like).
This code has been tested thoroughly in provision, and is the basis of a whole mess of neat functionality we discussed previously.
What's left to do is implementing the error codes intelligently across the board, and it also probably means that drush_die has to .. die. By exiting, you stop the ability to handle errors that may have occurred and provide rollback to the previous system state.
Comment #4
moshe weitzman CreditAttribution: moshe weitzman commentedYeah, I think we should move some of the error codes to provision. BUt that begs another question - how are modules supposed to define their own error codes and have them properly namespaced. We use module prefixes for namespacing so I wonder if it would work to use string based error codes. IDs are poorly extensible by modules - we have this problem with filter formats and build_modes for nodes.
I hope others take a look at this patch and give some feedback.
Likely needs reroll now that command arguments is in.
Comment #5
adrian CreditAttribution: adrian commentedI think i've figured out the following general error codes :
1 = Success. If there are no error codes, this is returned.
2 = Command not found.
4 = Drupal bootstrap error - IE: couldn't find a settings.php even tho we needed one
8 = Drupal DB error. - We have discussed this before, basically, we need to use output buffering and the shutdown function to catch the exit() from db_set_active.
16 = File permission error - This is very common so could use a constant.
32 = Framework / Application error.
255 = Generic PHP error. This means the script could not be interpreted, etc.
drush_set_error would then accept either one of the constants we define, or a string.
When a string is passed, it will automatically add a 32 to the bitmask, and store the errors in an associative array.
We can use the drush_help hook to provide the text to be used when an error occurs. (ie: instead of the inline printing, the messages will be mapped to keys in the error array)
When in verbose mode, the error is immediately printed.
When in backend mode (a patch I also want to introduce, that allows drush commands to call each other),
it will return the errors and the exit code along with the module defined errors/ error messages.
This allows the errors to be extendable infinitely, and gives calling scripts the ability to access the specific error messages they need.
This ties into the following issue for hosting/provision : http://drupal.org/node/275511
Comment #6
moshe weitzman CreditAttribution: moshe weitzman commentedthe new list looks much smaller and neater ... note my question earlier about module defined errors and numeric vs. string.
Comment #7
adrian CreditAttribution: adrian commentedHere is an updated patch for the logging system. It's behaviour is as follows :
1) it provides a small subset of the most common, and nondescript errors that could occur, defined as constants.
2) One of the error constants is a 'catch all' used for extending in your own way.
3) You can also provide a simple string (or define your own constant matching that string).
a) if you specify the optional message, it will log it for you using drush_log.
b) If a message is not specified, it will call hook_drush_help with the parameter or 'error:MY_ERROR_STRING'
c) If no message is found in help, it will use the error string itself as the error.
4) Scripts can use drush_get_errors() at any point to check if an error status has occurred.
5) If you need to check if a specific error has occurred, you can use drush_cmp_error('MY_ERROR_STRING').
This gives a script the ability to do things like flag that a download has failed, and recover more gracefully in that situation.
This feature is heavily used in the proposed drush_invoke() api, which allows you to extend any drush command by placing code either before, during or after the execution of that command. If an error is generated at any time during the invocation of the script, it
will then allow you to reverse changes gracefully.
Comment #8
moshe weitzman CreditAttribution: moshe weitzman commentedLooks OK to me at first glance, though I'm not really tuned in to all that this enables. I would love reviews from others on this.
I noticed a few PROVISION_FRAMEWORK_ERROR which should be changed to DRUSH_FRAMEWORK_ERROR I think.
Comment #9
adrian CreditAttribution: adrian commentedChanged to drush_framework_error.
The basic idea is that this API gives us a central place to log and track errors, so that instead of having to check return codes for all the various things that can go wrong, that then need to be bubbled up through the API, you can just use drush_get_errors().
The expanded error statuses are also accessible to external calling applications.
Comment #10
adrian CreditAttribution: adrian commentedI've cleaned it up a bit, so that any errors that get stored in the error control array, are now stored with their textual representation,
this simplified both the logging and the drush_cmp_error function, which is used to detect if a specific error has occurred.
In drupal terms, this API is analogous to form_set_error/form_get_errors, with the added benefits that errors also modify the return code, and the message can be provided by hook_drush_help.
The logging API that got committed, is analogous to drupal_get_messages and drupal_set_message. I actually have a function which I need to make a patch for, that will integrate any messages that drupal generates, and any PHP errors that occur, into the central logging system. So if you were writing a command that does a drupal_execute, any validation errors would also be displayed through the central logging system.
The invoke API is somewhat similar to FAPI in design, without the tree building and nested iteration, and it uses the above API in a very similar way that fapi does (ie: in validate you can trigger an error to stop execution of the _submit calback). It has the added benefit in that triggering an error causes a cleanup/rollback phase, where you can gracefully recover from filesystem manipulations etc.
The benefits to drush of these API's, is also similar in nature to the benefits of FAPI to core.
Comment #11
adrian CreditAttribution: adrian commentedHere's a related patch for handling the DRUSH_DRUPAL_DB_ERROR status : http://drupal.org/node/374765
Comment #12
adrian CreditAttribution: adrian commentedHere's my latest version of the patch.
Comment #13
moshe weitzman CreditAttribution: moshe weitzman commentedCommitted after reviewing code and some testing. Thx Adrian.