Exception handling at program startup

Specially GUI applications can show a undesiderable behavior if the encounter a failure before the GUI is initialized. That can be a missing and needed DLL, a runtime error in the initialization of the GUI itself or some other undesired behavior. The solution is to implement an own startip method that uses alternative ways to display the error and exit, maybe using the Windows Console and/or writing to an error log. The implementation differs a bit depending if you have a migrated VO application or a natively written .NET application mainly because of the different handling of namespaces. For the handling of namespace in migrated applications please see here: /ins Compiler option This is a sample code for an own startup class in a migrated application:

using System.Runtime.InteropServices
class XStartupCode
[STAThreadAttribute];
static method Start() as void strict
  local oSB as System.Text.StringBuilder

  try

  StartupExceptionTester.Exe.Functions.Start()

  catch oEx as Exception

  AllocConsole()
  oSB := System.Text.StringBuilder{}
  Output( oSB, "An unhandled exception has occurred" )
  Output( oSB, "===================================" )
  do while oEx != null
    Output( oSB, "Exception: " + oEx:Message )
    Output( oSB, "Callstack:")
    Output( oSB, oEx:StackTrace )
    Output( oSB, "" )
    oEx := oEx:InnerException
  enddo
  Output( oSB, "===================================" )
  Output( oSB, "Press Return to close the application" )
  Console.ReadLine()
  MessageBox( 0, oSB:ToString(), "Runtime error", 0 )
  System.IO.File.AppendAllText( System.IO.Path.Combine( AppDomain.CurrentDomain:BaseDirectory, "ApplicationError.log" ), oSB:ToString() )

  end try

return

static method Output( oSB as System.Text.StringBuilder, cText as string ) as void
  oSB:AppendLine( cText )
  Console.WriteLine( cText )

  return

[DllImport("kernel32.dll", SetLastError := true)];
[return: MarshalAs(UnmanagedType.Bool)];
static extern method AllocConsole() as logic

[DllImport("user32.dll", CharSet := CharSet.Ansi)];
static method MessageBox(hwnd as IntPtr, lpText as string, lpCaption as string, uType as dword) as int pascal

end class

To define this class as startup class, you have to add a compiler option:

-main:XStartupCode

Please see here for a sample as XIDE application export file: startupexceptiontester.zip

For a native .NET application with namespaces the code changes a bit:

class ProdPlan.XStartupCode

[STAThreadAttribute];
static method Start as void
local oSB as System.Text.StringBuilder

where ProdPlan is the namespace of your application. The compiler option than has to be

-main:ProdPlan.XStartupCode

To explain: since the GUI can be not yet started when an exception is occurring, the console mode needs to be activated so the error can be shown even with no GUI (and written to a file for later evaluation).