Alpha Error Handlers
Name:Error
Version:1.2
Last update:2020-10-21 07:12:05





The error.tcl package provides a uniform mechanism for catching, handling, and displaying errors. The key to all this functionality is a try construct, similar to that available in C++ or AppleScript. The default error handler will display any errors in accordance with the current user preferences (see the Errors Preferences panel).
Errors can be reported in one of four levels of detail: A fifth option is available only through the -reporting parameter to try, and is primarily for use by Alpha's startup code: Important: since version 8.6, Tcl introduced a [try] command. To avoid conflicts, the try proc defined in this package has been renamed alpha::try.

Examples

The script
alpha::try {
    error "this is the error" "" "this is the code"
}
will be reported as follows, depending on the value of errorReporting: In the event that there are errors that you don't wish to display or which to handle in some special fashion, supply one or more -onError scripts:
alpha::try {
	eval $script
} -onError {
	-34 {error::alertnote "Aughh!!! The disk is full!!!"}
	12* {error::alertnote "VOODOO error: $errorMsg"}
	default {}
}
will display a dialog reporting Aughh!!! The disk is full!!!, if you've executed
set script {error "this is an error" "" "-34"}
a dialog reporting VOODOO error: this is an error if you've executed
set script {error "this is an error" "" "12005"}
and does nothing at all for any other errors; in fact,
alpha::try {
	eval $script
} -onError {
	default {}
}
is identical to
catch $script
(and is, hence, a pretty stupid use of alpha::try, since it's noticeably slower). Another pointless use of alpha::try is
alpha::try {
	eval $script
} -onError {
	default error::rethrow
}
which is identical to
eval $script
(not to say that error::rethrow isn't handy, though).
Unless explicitly overridden, the default script will display all errors not accounted for by other -onError scripts. Always be sure to put the default script last or none of the other onError scripts will be executed.
The above case is OK, but rather than just catching 12000 series VOODOO errors, it will also catch errorCodes of "123", "12x", "12 buckle my shoe", and so on. Better, in this instance, would be to use the -regexp option
alpha::try {
	eval $script
} -onError {
	-34 {error::alertnote "Aughh!!! The disk is full!!!"}
	{12[0-9][0-9][0-9]} {error::alertnote "VOODOO error: $errorMsg"}
	default {}
} -regexp
As usual, the default behavior is clearer; the -regexp behavior is more powerful.

Reference

The alpha::try proc

Try to execute script. Synopsis:
    alpha::try script ?options?
The alpha::try command executes its script argument in the stack frame that called it. In the event of an error, alpha::try matches the global errorCode against each of any pattern arguments, specified by the -onError parameter, in order. As soon as it finds a pattern that matches errorCode it evaluates the following body argument by passing it recursively to the Tcl interpreter and returns the result of that evaluation. The last pattern argument is always a default to display the error (you may explicitly define a default argument if this behavior is not desired). Optionally, the errorMsg can be used for comparison, instead of errorCode.
The syntax is largely that of [switch], although the options follow script for both syntactic and performance reasons. The default comparison mode for alpha::try is -glob, instead of -exact. Unlike switch, alpha::try does not support separate pattern/command arguments; all must be provided as a list argument to the -onError optional parameter. The following options are currently supported:
-onError {pattern body ?pattern body ...?}
errorCode is compared to each pattern in order. When a match is found, body is executed in the stack frame that called alpha::try. If this option is missing, all errors will be displayed by the default routine.
-exact
Use exact matching when comparing errorCode to a pattern.
-glob
When matching errorCode to the patterns, use glob-style matching (i.e. the same as implemented by the [string match] command). This is the default.
-regexp
When matching errorCode to the patterns, use regular expression matching (i.e. the same as implemented by the [regexp] command).
-display
Override the user's setting for errorDisplay. Options are 'alertnote always', 'alertnote preferred', and 'window always'.
-reporting
Override the user's setting for errorReporting. Options are taciturn, terse, verbose, pedantic, and log.
-while
Short phrase to describe action taking place in event of an error.
-code
Match errorCode against the -onError patterns. This is the default.
-message
Match the errorMsg against the -onError patterns.
The -onError scripts execute in the frame that calls alpha::try, so all variables local to that frame are available, as are the global variables errorCode, errorInfo, and errorMsg (without having to declare them global).
If a body is specified as "-", it means that the body for the next pattern should also be used as the body for this pattern (if the next pattern also has a body of "-" then the body after that is used, and so on). This feature makes it possible to share a single body among several patterns.
Below are some examples of alpha::try commands:
    alpha::try {
         error "" "" aaab
     } -onError {
       ^a.*b$ -
       b {format 1}
       a* {format 2}
       default {format 3}
     } -regexp
will return 1, and
    alpha::try {
         error "" "" xyz
     } -onError {
       a
         -
       b
         {format 1}
       a*
         {format 2}
       default
         {format 3}
     }
will return 3.
Note: The old -depth option has been eliminated to allow delayed argument processing, resulting in an 80% speed increase for error-free scripts. Instead of
    alpha::try {script} -depth n
now use
    try::level n {script}
to achieve the same result.
Note: An alpha::try block adds about 0.6 ticks to the execution of an error-free script on my 7100/66 so, judiciously applied, there's not much of a penalty in using it.

The try::level proc

Try to execute script at specified level. Synopsis:
    try::level level args
Try to execute a script at a specified level in the execution stack (see [uplevel]). The remaining arguments are those of alpha::try.

The error::rethrow proc

Rethrow a caught error. Synopsis:
    error::rethrow
In the event that you catch an error you don't wish to handle, call this routine to send the error back to the caller.

Known problems

Please report any problem or bug you encounter to Alpha's Bug Tracker.

License and Disclaimer

Copyright (c) 1998-2020, Jonathan Guyer.
All rights reserved.
The Error package is free software and distributed under the terms of the new BSD license:
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JONATHAN GUYER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.