Seite 1 von 2

TryCatch - PBOSL Example

Verfasst: 25.02.2006 23:02
von remi_meier
Da ich ziemlich überzeugt davon bin, dass TryCatch eine bessere Übersicht
erlaubt und einige Fehler weniger hat als OnError von PB, erlaube ich mir
hier ein wenig Werbung mit einem Beispiel zu machen.

Was macht hier z. B. die OnErrorLib? :

Code: Alles auswählen

; Debugger ausschalten!!!

Procedure doof(a.l, b.l)
	; Prozedur mit lokalen Variablen/Parametern
	
	OnErrorGoto(?error)
	CopyMemory(a, b, 50)
	MessageRequester("Ging", "Lief?")
	
	
	error:
	ClearError()
	MessageRequester("Werte der Variablen", "a:" + Str(a) + " b:" + Str(b))
	ProcedureReturn
EndProcedure


doof(1, 1)
MessageRequester("Ende", "ProgrammEnde")
Nicht wirklich schön, oder? Falsche Variablenwerte (Esp nicht gesichert),
jede Menge Fehlermeldungen und das Programmende wird trotzdem nicht
ausgeführt, d. h. der letzte MessageRequester() wird nicht gezeigt...

PBOSL Variante:

Code: Alles auswählen

; Arbeitet sogar mit Debugger zusammen, d. h. der Exception-Handler
; vom Debugger wird überschrieben (und wiederhergestellt)

Procedure doof(a.l, b.l)
	; Prozedur mit lokalen Variablen/Parametern
	
	If TryError()
		CopyMemory(a, b, 50)
		MessageRequester("Ging", "Lief?")
	Else
		MessageRequester("Werte der Variablen", "a:" + Str(a) + " b:" + Str(b))
	EndIf : EndTryError()
	ProcedureReturn
EndProcedure


doof(1, 1)
MessageRequester("Ende", "ProgrammEnde")
Sauberes Programmende! Natürlich will ich nicht sagen, OnError sei total
unbrauchbar, immerhin liefert es einige Informationen mehr über den
Fehler! Trotzdem ist man mit TryCatch näher am Fehler dran und kann
deshalb gut darauf reagieren.

Hier nun eine noch schöner anwendbare Variante mit Makros:

Benötigt PBOSL und PB > 4.0

Code: Alles auswählen

Macro Try
	If TryError()
EndMacro

Macro Catch
	ElseIf GetTryErrorCode() = 
EndMacro

Macro CatchM(e1, e2=0, e3=0, e4=0, e5=0, e6=0, e7=0)
	ElseIf GetTryErrorCode() = e1 Or GetTryErrorCode() = e2 Or GetTryErrorCode() = e3 Or GetTryErrorCode() = e4 Or GetTryErrorCode() = e5 Or GetTryErrorCode() = e6 Or GetTryErrorCode() = e7
EndMacro

Macro CatchAll
	Else
EndMacro

Macro EndTry
	EndIf:EndTryError()
EndMacro



; Mögliche Exceptions:
; #EXCEPTION_ACCESS_VIOLATION
; #EXCEPTION_ARRAY_BOUNDS_EXCEEDED
; #EXCEPTION_BREAKPOINT
; #EXCEPTION_DATATYPE_MISALIGNMENT
; #EXCEPTION_FLT_DENORMAL_OPERAND
; #EXCEPTION_FLT_DIVIDE_BY_ZERO
; #EXCEPTION_FLT_INEXACT_RESULT
; #EXCEPTION_FLT_INVALID_OPERATION
; #EXCEPTION_FLT_OVERFLOW
; #EXCEPTION_FLT_STACK_CHECK
; #EXCEPTION_FLT_UNDERFLOW
; #EXCEPTION_ILLEGAL_INSTRUCTION = $C000001D
; #EXCEPTION_IN_PAGE_ERROR
; #EXCEPTION_INT_DIVIDE_BY_ZERO
; #EXCEPTION_INT_OVERFLOW
; #EXCEPTION_INVALID_DISPOSITION = $C0000026
; #EXCEPTION_NONCONTINUABLE_EXCEPTION = $C0000025
; #EXCEPTION_PRIV_INSTRUCTION
; #EXCEPTION_SINGLE_STEP
; #EXCEPTION_STACK_OVERFLOW = $C00000FD


DisableDebugger


Procedure doof()
	doof()
EndProcedure



Try
	; Jede Menge Fehler ->
	; einen nach dem anderen auskommentieren
 	!INT 4
 	!INT 3
 	a = a / 0
	doof()
	!HLT
Catch #EXCEPTION_ACCESS_VIOLATION
	MessageRequester("Fehler", "Access Violation!")
Catch #EXCEPTION_INT_DIVIDE_BY_ZERO
	MessageRequester("Fehler", "Division by 0!")
CatchM(#EXCEPTION_BREAKPOINT, #EXCEPTION_INT_OVERFLOW)
	MessageRequester("Fehler", "Breakpoint or IntOverflow!")
CatchAll
	MessageRequester("Fehler", "Fehler: " + Hex(GetTryErrorCode()))
EndTry

greetz
Remi

Verfasst: 25.02.2006 23:25
von ts-soft
Die entsprechenden Libs für PB4 findet ihr hier:
http://forums.purebasic.com/german/viewtopic.php?t=6788

Verfasst: 27.03.2006 10:49
von tomijan
@remi_meier
Hi!
Deine lib ist sehr nutzbar! Ich wartete an Try-Catch in PB 4, aber dorth finde ich das nicht.
Kannst du aber erklaeren, was genau "Be sure to NOT use TryError over procedures because PB cannot clean up the local variables!" bedeutet?
Ist ja sicher try- catch in proceduren benutzen ? Was mit return werte?

tom

Verfasst: 27.03.2006 16:13
von remi_meier
PBOSL_TryCatch für PB4 gibt es unter
http://purebasic.ts-soft-online.de/dl/p ... binary.zip
Das mit dem "over" ist etwas mühsam zu erklären. TryCatch innerhalb
von Prozeduren zu benutzen ist kein Problem. Aber wenn ein Aufruf einer
Prozedur im Try-Block steht und einen Fehler verursacht, dann wird vom
Ort des Fehlers direkt AUS der Prozedur rausgesprungen, d. h., dass
das Freigeben von z. B. lokalen Arrays dann "vergessen" wird. Somit
können Speicherlecks entstehen. Bei solchen Fehlern sollte deshalb immer
das Programm möglichst schnell neu gestartet werden.
Beispiel wie es gefährlich ist:

Code: Alles auswählen

If TryError()
  Prozedur1()
  Prozedur2() ; Verursacht einen Fehler
Else
  ; mach normal weiter
EndIf : EndTryError()
Es soll mehr eine Warnung sein, dass diese Library zum Abfangen von
_richtigen_ Fehlern da ist, d. h. man soll nicht aus Spass ein Var / 0 ein-
fügen, um die Prozedur mit einem Fehler zu verlassen, auch SetTryError-
Code() ist nicht besser und sollte nur in Notfällen angewandt werden.

In anderen Sprachen (z. B. Java) ist das kein Problem, da dort Try-Catch
direkt in der Sprache eingebaut ist und somit der Compiler acht geben
kann, welche lokalen Arrays/Listen/etc. freigegeben werden müssen im
Falle eines Fehlers.

Falls das noch nicht klar genug war, werde ich es gerne nochmals versuchen
zu erklären :)

greetz
Remi

PS: Der Grundbaustein dieser Funktionen wurde übrigens von Rings ge-
legt!

Verfasst: 27.03.2006 18:57
von tomijan
Vielen dank!
Deine library helfte mir mit einen error, welches eine exception C000005 bringt. Try-catch nimt das und ich koenne jetzt weiter mit meinen programm fahren (und fehler suchen)! Ohne dies das ganze programm endet sich ohne jene errormessage oder (am besten) haengt.
(es handelt sich um einen programm, welches acm conversion macht)

tom
leider ich koenne nur ein bischen deutsch!

Verfasst: 27.03.2006 19:32
von MVXA
Schön :D! Jetzt wo ich ein Beispiel hab kann ich mir überlegen wo ich
das einsetzen kann ^^. Danke!

Verfasst: 27.03.2006 19:33
von remi_meier
tomijan hat geschrieben:Deine library helfte mir mit einen error, welches eine exception C000005 bringt.
Freut mich sehr :)
tomijan hat geschrieben:leider ich koenne nur ein bischen deutsch!
Macht nichts, kannst sonst aber auch ein wenig Englisch reden, wenn es dir
besser läuft.

Verfasst: 27.03.2006 21:32
von tomijan
Noch eine Frage:
Functionen GetTryErrorLine() und GetTryErrorIncludeFile() (aus hilfe file)
geben einen Faehler (not a function, array or linked list).
Sind sie implemented?

tom

Verfasst: 29.03.2006 17:12
von remi_meier
Eigentlich schon, ev. hast du nicht die neuste Version der Libs oder ts-soft
hat vergessen die Libs neu hochzuladen :wink:

Verfasst: 29.03.2006 17:56
von ts-soft
remi_meier hat geschrieben:ts-soft hat vergessen die Libs neu hochzuladen :wink:
Ich kenne den ts-soft, der vergißt nur selten etwas
:wink: