TryCatch - PBOSL Example

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
remi_meier
Beiträge: 1078
Registriert: 29.08.2004 20:11
Wohnort: Schweiz

TryCatch - PBOSL Example

Beitrag 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
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Die entsprechenden Libs für PB4 findet ihr hier:
http://forums.purebasic.com/german/viewtopic.php?t=6788
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
tomijan
Beiträge: 24
Registriert: 28.01.2006 12:50

Beitrag 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
Benutzeravatar
remi_meier
Beiträge: 1078
Registriert: 29.08.2004 20:11
Wohnort: Schweiz

Beitrag 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!
tomijan
Beiträge: 24
Registriert: 28.01.2006 12:50

Beitrag 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!
Benutzeravatar
MVXA
Beiträge: 3823
Registriert: 11.09.2004 00:45
Wohnort: Bremen, Deutschland
Kontaktdaten:

Beitrag von MVXA »

Schön :D! Jetzt wo ich ein Beispiel hab kann ich mir überlegen wo ich
das einsetzen kann ^^. Danke!
Bild
Benutzeravatar
remi_meier
Beiträge: 1078
Registriert: 29.08.2004 20:11
Wohnort: Schweiz

Beitrag 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.
tomijan
Beiträge: 24
Registriert: 28.01.2006 12:50

Beitrag 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
Benutzeravatar
remi_meier
Beiträge: 1078
Registriert: 29.08.2004 20:11
Wohnort: Schweiz

Beitrag von remi_meier »

Eigentlich schon, ev. hast du nicht die neuste Version der Libs oder ts-soft
hat vergessen die Libs neu hochzuladen :wink:
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag 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:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Antworten