The NormalException class is the superclass of all non-fatal exceptions. You may occasionally want to define exceptions other than those automatically captured by the system. In this case, create a subclass of the NormalException class in order to add new properties and methods specific to your own exception protocol or to override system methods such as the
The method in the following example arms the exception handler so that the exceptionHandler method is called when an exception of the NormalException class is encountered and is passed the exception object as a parameter.
method1(); begin on NormalException do exceptionHandler(exception); self.method2; status.caption := "Resuming execution after exception throwing method invocation"; end;
The method in the following example causes a 1035 - String Too Long exception, by assigning a four-character string to a variable defined as being a three-character string.
method2(); vars str : String[3]; begin str := "Long string value"; end;
The method in the following example arms the exception handler so that the exceptionHandler method is called when an exception of the UserException class is raised and is passed the exception object as a parameter.
method3(); begin on UserException do exceptionHandler(exception); self.method4; end;
The method in the following example creates an object of the UserException class and defines the properties for this object. The exception is then raised.
method4(); vars ex : UserException; begin create ex; ex.errorCode := 64000; ex.continuable := true; ex.resumable := true; raise ex; status.caption := "Resuming execution after raising of exception"; end;
The following is an example of an exceptionHandler method in a UserException subclass of the NormalException class.
exceptionHandler(ex: NormalException): Integer; vars returnCode : Integer; begin // Exception handling method specified when arming the handler, and // called when the appropriate exceptions are raised. If the error // code of the exception is 1035, the exception is identified as // being the String Too Long exception and is handled appropriately. if ex.errorCode = 1035 then returnCode := app.msgBox("String too long. Resume execution after method?", "String too long", 52); if returnCode = MsgBox_Return_Yes then // The Ex_Resume_Next return value passes control back to // the method that armed the exception handler (in this // case, method1) and resumes execution after the // invocation of the method that raised the exception. return Ex_Resume_Next; else // The Ex_Abort_Action return value causes all currently // executing methods to be aborted. In this case, the // application reverts to execution after the invocation // of the method that raised the idle state, and awaits // further user input. status.caption := "Aborting all currently executing methods"; return Ex_Abort_Action; endif; // If the error code of the exception is 64000, the exception is // identified as the user-defined exception that was assigned this // code, and is handled appropriately. elseif ex.errorCode = 64000 then returnCode := app.msgBox("User-defined exception. Continue method execution?", "User-defined exception", 52); if returnCode = MsgBox_Return_Yes then // The Ex_Continue return value passes control back to the // method that raised the exception handler (in this case, // method4) and resumes execution after raising the exception. return Ex_Continue; else // The Ex_Resume_Next return value passes control back to the // method that armed the exception handler (in this case, // method1) and resumes execution after the invocation of // the method that raised the exception. status.caption := "Resuming execution after exception throwing method invocation"; return Ex_Resume_Next; endif; endif; end;