Handling Exceptions in the .NET Environment

The PowerBuilder to .NET compiler changes the exception hierarchy used by the native PowerScript compiler.

Modified exception hierarchy

In the native PowerBuilder environment, Throwable is the root datatype for all user-defined exception and system error types. Two other system object types, RuntimeError and Exception, inherit directly from Throwable.

In the .NET environment, System.Exception is the root datatype. The PowerBuilder to .NET compiler redefines the Throwable object type as a subtype of the System.Exception class, and maps the .NET System.IndexOutOfRangeException class to the PowerBuilder RuntimeError object type with the error message “Array boundary exceeded.” The PowerBuilder to .NET compiler also maps the following .NET exceptions to PowerBuilder error objects:
  • System.NullReferenceException class to the NullObjectError object type

  • System.DivideByZeroException class to the DivideByZeroError object type

This figure shows the exception hierarchy for PowerBuilder applications in the .NET environment:

Exception hierarchy for PowerBuilder in the .NET environment
System.Exception is the root exception class. Throwable inherits directly from System.Exception as do user defined exceptions from C# or VB .NET.  The System.Index.OutOfRangeException, System.NullReferenceException, and System.DivideByZeroException map respectively to the PowerBuilder RuntimeError, NullObjectError, and DivideByZeroError object types.

Example using a .NET system exception class

Even though a .NET exception class is mapped to a PowerBuilder object type, you must use the PowerBuilder object type in your PowerScript code. For example, suppose you define a .NET test class to test for division by zero errors as follows:
namespace ExceptionSample
{
  // Custom exception class used in method second_test(int a) below
  public class MyCustomException : Exception
  {
    public string GetMessage()
    {
       public string GetMessage() 
       {
          return "Custom Error Thrown";
       }
    }
    public class Test
    {
      public int division_test (int a)
      {
         int zero = 0;
         // this will throw a System.DivideByZero exception
         return a/zero; 
      }
      public int second_test(int a)
      {
         a = a / 2;
         throw new MyCustomException();
      }
  }
} 
To catch the error in PowerScript, you can use the DivideByZeroError object type or either of its ancestors, RuntimeError or Throwable. The following PowerScript code catches the error caused by the call to the .NET Test class method for invoking division by zero errors:
int i = 10
string ls_error
try
   #IF Defined PBDOTNET Then
     ExceptionSample.Test t
       t = create ExceptionSample.Test
     i = t.division_test(i)
   #END IF
catch (DivideByZeroError e)
//the following lines would also work:
//catch (RuntimeError e)
//catch (Throwable e)
   ls_error = e.getMessage ( )
   MessageBox("Exception Error", ls_error)
end try

Example using a custom .NET exception class

Suppose the .NET Test class is modified to catch a custom .NET exception:
public class Test
{
   public int second_test (int a)
   {
      a = a/2; 
      throw new MyUserException();
   }
} 
Because MyUserException is a user-defined exception in the .NET environment, it cannot be caught by either the PowerBuilder Exception or Throwable object types. It must be handled inside a .NET conditional compilation block:
int i = 10
string ls_error 
#IF Defined PBDOTNET Then
   try
     ExceptionSample.Test t
       t = create ExceptionSample.Test
     i = t.second_test(i)
   catch (ExceptionSample.MyUserException e)
   //this will also work: catch (System.Exception e)
     ls_error = e.getMessage()
       MessageBox("Custom Exception", ls_error)
   end try
#END IF