TkScript |
|
reference guide | Exceptions |
1. Introduction
Exceptions are used to signal errors which occured while executing a script or native code function or method.
An exception usually propapates up the callstack until it is either caught in a try
.. catch
statement or until it is caught by the root exception handler which simply prints out the exception and terminates the program.
Exceptions can either be fatal (derived from CriticalError
) or expected (derived from UncriticalError
).
2. Inheritance
Exceptions support single-inheritance, i.e. an exception type is derived from exactly one base exception type.
The Error
exception type is the base type for all other exception types. It is the only exception type that has no parent type.
2.1. Pre-defined exception types
The following exception (or error) types are pre-defined by the TkScript runtime:
- Error
- CriticalError
- InvalidPointer
- Death
- TypeMismatch
- ClassTypeMismatch
- NativeClassTypeMismatch
- ScriptClassTypeMismatch
- NotFound
- ClassMethodNotFound
- NativeClassMethodNotFound
- ScriptClassMethodNotFound
- ClassMemberNotFound
- NativeClassMemberNotFound
- ScriptClassMemberNotFound
- ModuleNotFound
- ModuleMemberNotFound
- ArrayOutOfBounds
- ReadArrayOutOfBounds
- WriteArrayOutOfBounds
- ConstraintViolation
- NotNullConstraintViolation
- UncriticalError
2.2. The "Exception" class
When an exception occurs, it will be wrapped in an
Exception
Object
.
The object will store that stack backtrace, as seen when the exception occured, along with the exception type (
id
) and a user defined message
String
.
Please notice that
one Exception
class is used to represent all possible
exception types.
Example:
try die("some message");
catch(Error e) {
Exception
x <= e; // just for clarification, could use "e" directly
trace "x. id=" + x.id;
trace "x. name=" + x.name;
trace "x. message=" + x.message;
trace "x.stacktrace=\n" + x.stackTrace;
}
3. Critical exceptions
The
CriticalError
exception type is the base type for all exception types that represent a fatal/critical error, like e.g. accessing a
null
pointer.
A critical error indicates a condition which has either not been anticipated by the programmer or which simply should not occur during regular program execution.
A critical error usually leads to the termination of the current program.
It is considered
bad practice to catch critical errors since they usually indicate a more serious software problem.
However, applications may choose to catch these errors and e.g. backup unsaved user data before exiting.
Example:
function Run() {
String
s <= null;
s.append("oh noes!");
}
try Run(); catch(Error e) {
/* deploy parachute */
trace "[---] something terrible went wrong !";
exit(10);
}
4. Uncritical errors
Exception types that are derived from UncriticalError
receive special treatment in the TkScript runtime: An uncritical exception causes the current function call to return but the exception will simply be discarded if it is not caught in the upper stackframe.
This mechanism is meant to support the actual idea of exceptions: To provide an error reporting and handling mechanism. Without forcing the programmer to wrap every second API call in a try
..catch
statement..
The return value of many API functions and methods often already indicates the success or failure of the respective call. In case more detailed error information is needed, e.g. in order to display it in a graphical user interface, the respective API function/method can utilize an UncriticalError
exception to provide further information about the cause of error.
4.1. Example
class Configuration
{
define exception ConfigurationError : UncriticalError;
define exception ConfigFileNotFound : ConfigurationError;
define exception ConfigParseError : ConfigurationError;
static LoadDefaults() {
/* ... */
}
protected static ParseConfig(String
buf) : boolean {
/* ... */
throw ConfigParseError("parser implementation missing..");
}
static Load() : boolean {
return = false;
LoadDefaults();
String
buf;
if(!buf.loadLocal("democonfig.ini", true))
{
throw ConfigFileNotFound("could not find \"democonfig.ini\"");
}
else
{
// Need to re-throw the uncritical error to prevent it from being removed automatically
try return ParseConfig(buf); catch(ConfigurationError e) throw e;
}
}
}
// This could simply be called this way:
if(Configuration.Load())
{
trace "[...] Configuration loaded.";
}
else
{
trace "[---] failed to load configuration.";
}
// OR (if more detailed error information is desired)
try {
Configuration.Load();
trace "[...] Configuration loaded.";
}
catch(ConfigurationError e) {
trace "[---] failed to load configuration (error="+e.name+", \""+e.message+"\").";
}
Notice how a function or method can both return a value
and throw an exception.
5. try / catch
If a statement or statement sequence is enclosed in a
try
and
catch
statement and an exception occurs within that statement(-sequence), the
catch
block that matches the exception type
best is executed.
The
catch
blocks will automatically be sorted by exception type respectively inheritance.
Each
try
statement can be followed by none, one or many
catch
statements.
Also see
The try..catch, finally statements
.
5.1. Finally
TkScript supports the
finally
clause which is commonly used to clean up resources before passing an exception to the caller.
The
finally
statement sequence is run after an exception has been handled in a
catch
block or if no exception was raised at all.
Example:
function Run() {
try {
throw InvalidPointer("d'oh");
}
finally {
// This code is run whether an exception has been thrown in try {} or not!
trace "[...] Run: cleaning up..";
}
}
Run();
The
finally
clause is
optional.
5.2. Exceptions in "catch" or "finally"
If an exception occurs while executing a catch
statement sequence, the new exception will replace the currently handled exception and the control flow will branch to the next outer try
..catch
statement or to the caller stackframe. The finally
statement sequence will not be executed in this case.
If an exception is thrown while executing the finally
statement sequence, the new exception will also replace the currently handled exception !
6. die
The
die
statement outputs a message to
stdout
and raises the
Death
exception.
Example:
die "..some error occured..";
Also see
The die statement
.
auto-generated by "DOG", the TkScript document generator. Wed, 31/Dec/2008 15:53:35