Table of Contents

11.5.1 Error detection and handling - Try, Finally and Catch

Especially when working with directories and files, errors can occur that are difficult to predict. They occur because, for example, files cannot be opened because part of the path specification is incorrect or they cannot be written to because the user does not have the necessary rights or a directory no longer exists to which a file is to be copied. However, it may also not be considered that a method requires an absolute (system) path and then a certain error is triggered. In all cases, error detection and error handling is required.

As usual in Gambas, the following keywords TRY, FINALLY and CATCH, the construct “IF ERROR THEN … ENDIF” and the event Application_Error() are used:

11.5.1.1 TRY

[1] Try TextArea1.Text = File.Load(".../help/help.txt")
[2] If Error Then 
[3]    Message.Error("The help file cannot be loaded.")
[4]    FHelp.Delete()
[5] Endif

If no error occurs when trying to load the help file, its contents are displayed in a text area. However, if the help file cannot be loaded, then the triggered error is not displayed - it is hidden. Therefore, in this case, lines 2 to 5 are executed, which at least inform about a present error. In the present case, the help file must not be displayed - but the programme continues to run.

11.5.1.2 FINALLY

In the next example, the Finally block is followed by a Catch block:

[1] Private Sub AddTextToFile(FilePath As String, Text As String)
[2]   
[3]   Dim hFile As File
[4]   
[5]   hFile = Open FilePath For Append
[6]   Finally
[7]     If Exist(FilePath) Then Close #hFile
[8]   Catch
[9]     Message.Error("Error:\n" & Error.Text & " in " & Error.Where)  
[10] End

In any case, the file is closed - the Finally block takes care of that. The (optional) Catch block would indicate an error occurring in lines 5 to 7.

11.5.1.3 CATCH

The following example uses only one catch block to display in a sufficiently differentiated manner all errors that occur with an appropriate error message:

[0] Public Sub btnHelpLibrary_Click()
[1]   Dim cl As Class
[2]   
[3]   cC = Component.Load(":gambasbook/LPathProject:1.2")
[4]   cl = Class.Load("Module1")
[5]   Object.Call(cl, cl.Symbols[0], Null)
[6]   Catch
[7]      Message.Error(Error.Text)
[8] 
[9] End

The two error messages below become understandable if, on the one hand, the library LPathProject cannot be loaded (error 1) and, on the other hand, Module1 is not available (error 2). In contrast, there was only the second error message when in the existing library the module with the specified name `Module1` did not exist.

B1

Figure 11.5.1.3.1: First error message

B2

Figure 11.5.1.3.2: Second error message

The catch block in the following example consistently catches all triggered errors and outputs a detailed error message. In addition, the last two procedures close the open files - if the file paths exist:

Public Sub btnAddTextToFile_Click()

  Dim sLogDir As String
  
  sLogDir = Desktop.DataDir &/ "gambasbook" &/ AppName 
  If Not Exist(sLogDir) Then Shell.MkDir(sLogDir)
  AddTextToFile(sLogDir &/ "rs232.log", "Time = " & Format(Now, "hh:nn:ss") & " - " & sTValue)
  Catch
    Message.Error("Error:\n" & Error.Text & " in " & Error.Where)
End

Public Sub btnGetTextFromFile_Click()

  Dim sLogPath As String
  
  sLogPath = Desktop.DataDir &/ "gambasbook" &/ AppName &/ "rs232.log"
  txaLog.Text = GetTextFromFile(sLogPath)
  Catch
    Message.Error("Error:\n" & Error.Text & " in " & Error.Where)
End

Private Sub AddTextToFile(FilePath As String, Text As String)
  
  Dim hFile As File
  
  hFile = Open FilePath For Append
  Finally
    If Exist(FilePath) Then Close #hFile
  Catch
    Message.Error("Error:\n" & Error.Text & " in " & Error.Where)  
End

Private Function GetTextFromFile(FilePath As String) As String

  Dim hFile As File
  Dim sLine, Text As String
  
  hFile = Open FilePath For Read  
   
  While Not Eof(hFile)
    Line Input #hFile, sLine
    Text &= sLine & "\n"
  Wend

  Return Text
  
  Finally
    If Exist(FilePath) Then Close #hFile
  Catch
    Message.Error("Error:\n" & Error.Text & " in " & Error.Where)
  
End

11.5.1.4 Event Application_Error()

Assumption: An error may be triggered for which neither a Try statement nor a Finally or Catch block is provided. This is exactly when you will use the Application_Error() event, for example, to write data into a file without fail or to delete a file under all circumstances before the programme ends. This event is triggered in the start class of the project. Only there can the event handling routine be located so that something happens and it must have the signature 'Static Public Sub Application_Error()'. The start class must not be a module.In the example, a lock file is created to prevent any attempt to create another instance of the application. If the programme ends without errors, the lock file is deleted. If the procedure RunATest() is executed, then the division by the divisor zero also takes place. An error is triggered, which is neither handled by a Try statement nor by a Finally or Catch block. The programme would crash - leaving the lock.file in the system. This would have the consequence that any further start of the programme would be prevented because there is already a lock file!

A way out is offered by the event Application_Error(), in whose event handling routine the lock.file is deleted - before all the lights go out … .

[1] ' Gambas class file
[2] 
[3] Public bFlag As Boolean = False
[4] 
[5] Public Sub _new()
[6]   
[7]   If Exist(Application.Path &/ ".lock.file") Then
[8]      Message.Warning(Subst("&1 '&2' &3", ("There is already an instance of"), Application.Name, "!"))
[9]      bFlag = False
[10]      FMain.Close()
[11]   Endif
[12] 
[13]   Shell "touch " & Application.Path &/ ".lock.file" Wait
[14] 
[15]   bFlag = True
[16]   
[17] End
[18] 
[19] Static Public Sub Application_Error() 
[20]   If Exist(Application.Path &/ ".lock.file") Then Kill Application.Path &/ ".lock.file" 
[21]   Wait   
[22] End 
[23] 
[24] Public Sub Form_Open()
[25]   FMain.Resizable = False
[26] End
[27] 
[28] Public Sub Form_Close()
[29]     If bFlag Then Try Kill Application.Path &/ ".lock.file"
[30]     FMain.Close()
[31] End
[32] 
[33] Public Sub btnTest_Click() 
[34]  RunATest() 
[35] End
[36] 
[37] Private Sub RunATest()
[38] 
[39]   Dim i As Integer
[40]   Dim q As Float
[41] 
[42]   For i = -2 To 2 
[43]     q = 5 / i 
[44]   Next 
[45] 
[46] End

B3

Figure 11.5.1.4.1: GUI

B4

Figure 11.5.1.4.2: Test error message.

Conclusion:

Download