Error System

Source: source/function/errsysw.prg

FiveWin replaces Harbour's default error handler with a GUI-based error dialog that displays detailed diagnostic information. The error system is automatically initialized at application startup via the ErrorSys() procedure, which sets an error block calling ErrorDialog().

Error Handling Flow

flowchart TD A[Runtime Error Occurs] --> B{Error Type?} B -->|Division by Zero| C[Return 0
silently] B -->|Network Open Error| D[Set NetErr .T.
Return .F.] B -->|Append Lock Error| E[Set NetErr .T.
Return .F.] B -->|Other Error| F[ErrorDialog] F --> G[Build Error Log] G --> H{bUserDlg set?} H -->|Yes| I[Call Custom Dialog] H -->|No| J[Show FWH Error Dialog] J --> K[User Chooses Action] K -->|Quit| L[Write error.log
QUIT] K -->|Retry| M[Return .T.] K -->|Default| N[Return .F.] K -->|Debug| O[AltD at error] L --> P{bUserAction set?} P -->|Yes| Q[Execute Post-Error Action] P -->|No| R[Application Exits]

Automatic Error Handling

Certain error types are handled automatically without showing the error dialog:

ErrorgenCodeAutomatic Action
Division by zeroEG_ZERODIVReturns 0 silently
Network open error (OS code 32 or 5)EG_OPENSets NetErr(.T.), returns .F.
Append lock errorEG_APPENDLOCKSets NetErr(.T.), returns .F.
Recursive error (7+ levels deep)anyForces QUIT to prevent infinite loop

Error Dialog

The FiveWin error dialog is a modern, feature-rich dialog that adapts to the system theme:

Error Log Format

When the user clicks "Quit", an error.log file is written (or appended). The log contains these sections:

Application
===========
   Path and name: C:\myapp\myapp.exe (32 bits)
   FiveWin version: FWH 26.05
   Harbour version: 3.2.0
   Date: 2026-03-24
   Time: 14:30:45

Error
=====
   Description: Argument error
   SubSystem: BASE
   Operation: +
   Args:
      [1] = C "Hello"
      [2] = N 42

Call Stack
==========
   Called from MAIN(25) in source\main.prg
   Called from PROCESSDATA(102) in source\process.prg
   ...

System
======
   OS: Windows 11 Build 22621
   Windows Directories
   Active tasks

Databases in use
================
   Area 1: CUSTOMERS (customers.dbf) RecNo: 42 RecCount: 1500
   ...

Customizing the Error System

SetErrorPath() / SetErrorFileName()

// Change error log location
SetErrorPath( "C:\logs\" )
SetErrorFileName( "myapp_error.log" )

SetErrorDialog() -- Custom Dialog

// Replace the entire error dialog with a custom one
SetErrorDialog( { |oDlg, e, cLog, aStack|
   // oDlg is the dialog being created
   // e is the error object
   // cLog is the error log text
   // aStack is the call stack array
   // Return: nil (use default buttons) or handle buttons yourself
} )

SetPostErrorAction() -- Post-Error Hook

// Execute code after the error dialog closes
SetPostErrorAction( { |e, cLog|
   // Send error report to server
   SendErrorReport( cLog )
   // or restart the application
   // WinExec( GetModuleFileName( GetInstance() ) )
} )

Custom ErrorBlock

// Replace the error handler entirely
ErrorBlock( { |e| MyErrorHandler( e ) } )

static function MyErrorHandler( e )

   // Log to file
   LogFile( "errors.log", { e:Description, e:Operation, ;
      ProcName(4), ProcLine(4) } )

   // Show simple message
   MsgStop( e:Description + CRLF + ;
      "at " + ProcName(4) + "(" + LTrim( Str( ProcLine(4) ) ) + ")" )

   // Quit the application
   PostQuitMessage( 0 )
   __Quit()

return nil

Example: TRY/CATCH Blocks

#include "FiveWin.ch"

function Main()

   local xResult

   // TRY/CATCH prevents the error dialog from showing
   TRY
      xResult := SomeRiskyOperation()
      MsgInfo( "Result: " + cValToChar( xResult ) )
   CATCH e
      MsgAlert( "Error: " + e:Description + CRLF + ;
         "Operation: " + e:Operation )
   END

return nil

Example: Custom Error Handler with Email

#include "FiveWin.ch"

function Main()

   // Install custom post-error action
   SetPostErrorAction( { |e, cLog|
      // Save error log
      MemoWrit( "crash_" + DToS( Date() ) + "_" + StrTran( Time(), ":", "" ) + ".log", cLog )

      // Could send email notification here
      // SendMail( "admin@company.com", "App Crash", cLog )
   } )

   // Change error log location
   SetErrorPath( "C:\logs\" )
   SetErrorFileName( "app_errors.log" )

   // ... rest of application ...
   AppMain()

return nil

Error Object Properties

The error object e passed to the error handler is a standard Harbour Error object:

PropertyTypeDescription
e:DescriptionCharacterHuman-readable error description
e:OperationCharacterThe operation that caused the error
e:SubSystemCharacterSubsystem name (BASE, DBCMD, etc.)
e:genCodeNumericGeneric error code (EG_*)
e:subCodeNumericSubsystem-specific error code
e:osCodeNumericOperating system error code
e:ArgsArrayArguments that caused the error
e:canRetryLogicalWhether retry is possible
e:canDefaultLogicalWhether default action is possible
e:canSubstituteLogicalWhether a substitute value can be returned
e:FileNameCharacterFile that caused the error (if applicable)

Multi-Language Support

The error dialog uses FWString() for all user-visible text, so it automatically adapts to the language set by FWSetLanguage(). Supported strings include "Application", "Path and name", "Date", "Time", error descriptions, and button labels.