You can write custom exception handlers to perform more complex exception processing. Handlers are blocks of code placed at the bottom of a procedure that execute after an exception is raised. Separating handlers out from the rest of the procedure keeps them from becoming entangled with the business logic to reduce complexity. When an exception is raised within the procedure or in any procedures that it invokes, a handler for that exception is run.
With Gilda, exceptions are discriminated by their context instead of by name. Naming exceptions runs into maintenance issues at scale. The problems are similiar to those that arise with Goto statment labels, but are worse as they result in undesirable coupling between methods.
Additionally Gilda exceptions are processed outside procedure bodies. When using status codes or the prevelent try-throw-catch model, exceptions resume within the procedure body. Exception processing unavoidably becomes embedded within the business logic. This makes it harder to write programs that behave well under duress and requires a level of programmer discipline that is rare.
After an exception is raised its context can first be accessed by a low level system wide handler. The Basis library includes a method that will return the initial context including a context string, a message, and a method name with the exception's line number, and an enumeration denoting the kind of exception that was raised.
From there handlers in methods up the call chain can be run that annotate the context by capturing local information and storing it in context variables within a Class. Classes can include special context variables that are intended only to be used within exception handlers.
Handlers begin with a Catch declaration designating the kind of exception to intercept. A procedure can contain mutiple handlers; each selecting a different kind of exception. After the catch declaration you can declare local variables and then code a block of statments to process the exception.
catch
catch fault
assert Condition catch Name; Message : catch Name
catch call Procedure.Name
catch context Variable.Name
catch class Class.Name
Each handler ends with a Return command. A Return with no arguments simply returns from the primary procedure. The "return raise" keyword always propagates the exception up the call chain. An optional variable conditionally either returns from the procedure or propagates the exception. When set to a non-zero value the exception will be propagated. Otherwise the handler will return normally from the primary procedure.
return
return raise
return Variable
The Hello World page discusses motivations for exception handling. The rationale for Gilda's exception model is detailed in the paper, Disentangling Exceptions. Here is another example of a handler that catches all exceptions in a method:
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: : method DO_SOMETHING: Example of catching and extending and exception. entry Value word, Text string alter Assertion :Access the assertion context in the library. : :......................................................................... IF Value < 0 assert Value < 100 pass Text; ERROR: Value too big. . PRINT Text, Value return :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: : catch: Extend an exception context with a note. : :......................................................................... Assertion`Note = "An exception occured in " & ! Assertion`Method ! " on line " & ! form( Assertion`Line ) return raise; Unwind to a higher level handler for reporting.