The Grace spec used to describe the top levels of the Exception hierarchy. It no longer does. I don't know when it was removed, or by whom, but I remember writing it, and wonder why it's not there.
Arguably the lower levels of the hierarchy should be in the standard library document, not in th language spec, but it seems to me that the upper levels need to be in the spec. Certainly, the NoSuchMethod exception is part of the language itself, as are other programming errors, such as returning from a block that is no longer in the context of the method that created it.
Here is what I found had been deleted:
Kinds of Exception
Grace defines a hierarchy of kinds of exception. All exceptions have the same type, that is, they understand the same set of requests. However, there are various kinds of exception, corresponding to various kinds of exceptional situation.
The exception hierarchy classifies these kinds of exception using ExceptionKind
objects, which have the following type:
type ExceptionKind = Pattern & {
parent -> ExceptionKind
// answers the exceptionKind that is the parent of this exception in the
// hierarchy. The parent of exception is defined to be exception. The parent
// of any other exceptionKind is the exception that was refined to create it.
refine (name:String) -> ExceptionKind
// answers a new exceptionKind, which is a refinement of self.
raise (message:String)
// creates an exception of this kind, terminating the current execution,
// and transferring control to an appropriate handler.
raise (message:String) with (data:Object)
// similar to raise(), except that the object data is associated with the
// new exception.
}
Because ExceptionKinds are also Patterns, they support the pattern protocol (match, &, and |). Perhaps more pertinently, this means that they can be used as the argument of the catch blocks in a try()catch()... construct.
At the top of the hierarchy is the Exception object; all exceptions are refinements of exception. There are three immediate refinements, of Exception:
EnvironmentException: those exceptions arising from interactions between the program and the environment, including network exceptions, file system exceptions, and inappropriate user input.
ProgrammingError: exceptions arising from programming errors.
Examples are IndexOutOfBounds, NoSuchMethod, and NoSuchObject.
ResourceException: exceptions arising from an implementation insufficiency, such as running out of memory or disk space.
Notice that there is no category for "expected" exceptions. This is deliberate; expected events should not be represented by exceptions, but by other values and control structures.
For example, if you you have a key that may or may not be in a dictionary, you should not request the at method and catch the NoSuchObject exception. Instead, you should request the at(_)ifAbsent(_) method.
Each exception is matched by the ExceptionKind that was raised to create it, and all of the ancestors of that kind of exception. Because Exception is the top of the exception hierarchy, it matches all exceptions.
Exceptions have the following type.
type Exception = type {
exception -> ExceptionKind // the exceptionKind of this exception.
message -> String // the message that was provided when this exception was raised.
data -> Object // the data object that was associated with this exception
// when it was raised, if there was one. Otherwise, the string "no data".
lineNumber -> Number // the source code line number
// of the raise request that created this exception.
moduleName -> String // the name of the module
// containing the raise request that created this exception.
backtrace -> List<String>
// a description of the call stack at the time that this exception was raised.
// backtrace.first is the initial execution environment; backtrace.last is the
// context that raised the exception.
}
Exceptions are distinguished by the name passed to the refine method when they were
created. Exception packets also contain a "data" field, which may be populated
with any object using the raise(_)with(_) method on exceptions:
MyException.raise "A message" with (anObject)
There is no behaviour or requirement attached to this object. It is simply stored to be used by the exception handler if desired.
A single handler may be defined for more than one kind of exception using the | pattern combinator:
try {
...
} case { e : MyError | AnotherError ->
...
}
This handler will be run when either MyError or AnotherError is raised inside the try block.
The Grace spec used to describe the top levels of the Exception hierarchy. It no longer does. I don't know when it was removed, or by whom, but I remember writing it, and wonder why it's not there.
Arguably the lower levels of the hierarchy should be in the standard library document, not in th language spec, but it seems to me that the upper levels need to be in the spec. Certainly, the
NoSuchMethod
exception is part of the language itself, as are other programming errors, such as returning from a block that is no longer in the context of the method that created it.Here is what I found had been deleted:
Kinds of Exception
Grace defines a hierarchy of kinds of exception. All exceptions have the same type, that is, they understand the same set of requests. However, there are various kinds of exception, corresponding to various kinds of exceptional situation.
The exception hierarchy classifies these kinds of exception using
ExceptionKind
objects, which have the following type:Because
ExceptionKinds
are alsoPatterns
, they support the pattern protocol (match
,&
, and|
). Perhaps more pertinently, this means that they can be used as the argument of the catch blocks in atry()catch()
... construct.At the top of the hierarchy is the
Exception
object; all exceptions are refinements ofexception
. There are three immediate refinements, ofException
:EnvironmentException
: those exceptions arising from interactions between the program and the environment, including network exceptions, file system exceptions, and inappropriate user input.ProgrammingError
: exceptions arising from programming errors. Examples areIndexOutOfBounds
,NoSuchMethod
, andNoSuchObject
.ResourceException
: exceptions arising from an implementation insufficiency, such as running out of memory or disk space.Notice that there is no category for "expected" exceptions. This is deliberate; expected events should not be represented by exceptions, but by other values and control structures. For example, if you you have a key that may or may not be in a dictionary, you should not request the
at
method and catch theNoSuchObject
exception. Instead, you should request theat(_)ifAbsent(_)
method.Each exception is matched by the
ExceptionKind
that was raised to create it, and all of the ancestors of that kind of exception. BecauseException
is the top of the exception hierarchy, it matches all exceptions.Exceptions have the following type.
Exceptions are distinguished by the name passed to the refine method when they were created. Exception packets also contain a "data" field, which may be populated with any object using the
raise(_)with(_)
method on exceptions:There is no behaviour or requirement attached to this object. It is simply stored to be used by the exception handler if desired.
A single handler may be defined for more than one kind of exception using the | pattern combinator:
This handler will be run when either
MyError
orAnotherError
is raised inside the try block.