Try/Catch/Finally error handling...

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
Little John
Addict
Addict
Posts: 4519
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Try/Catch/Finally error handling...

Post by Little John »

Dawgmann wrote:@ Little John
Little John wrote:In the beginning of this thread, it looked as if you wanted to start a serious discussion ...
It is a serious discussion.
My remark referred to the quotation in the same post, which is anything but serious.
Dawgmann wrote:Just because you may not see a need for a particular tool or programming method and may be a fanboy of another doesn't mean someone else doesn't have a need for it. You don't get to dictate that. And I don't care if you've been programming in a language for 40 years - your ego still does not rule other people's needs. If you don't have a need for it yourself, just don't use it.
:?: :?: Did I dictate anything? No. Did I write that I've been programming in a language for 40 years? No. Does this blah blah have got anything to do with what I wrote previously? No.
People who can read and understand simple text have got an advantage.
Dawgmann wrote:In such case, please suggest a viable work-around to achieve the goal, or just don't chime in at all.
At first, I was following this thread with interest, and I might have contributed to it sooner or later. If and when I'm going to do that is not your decision, but solely mine. However, when you posted your Foot Doctor polemics, I realized that a serioius discussion with you obviously is not possible. You just confirmed that with your recent reply.
Dawgmann
User
User
Posts: 40
Joined: Wed Jul 17, 2019 5:32 pm

Re: Try/Catch/Finally error handling...

Post by Dawgmann »

@ Little John

I deeply apologize. That last part was meant for someone else and I have corrected that post.
Dawgmann
User
User
Posts: 40
Joined: Wed Jul 17, 2019 5:32 pm

Re: Try/Catch/Finally error handling...

Post by Dawgmann »

Okee dokee...

After several more hours of testing the error handling capabilities, I've come to the unfortunate conclusion that PB just can't meet my needs. So, I've decided to discard it in favor of moving forward with another language/system that I've been testing simultaneously.

So, the moderators can feel free to delete this feature request post (and all my other ones too) as I will no longer have a need for it.
User avatar
skywalk
Addict
Addict
Posts: 3972
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: Try/Catch/Finally error handling...

Post by skywalk »

Did you disable the debugger when testing the try catch?
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
Bitblazer
Enthusiast
Enthusiast
Posts: 732
Joined: Mon Apr 10, 2017 6:17 pm
Location: Germany
Contact:

Re: Try/Catch/Finally error handling...

Post by Bitblazer »

Dawgmann wrote:Using all the example I could find using PB's 'OnErr' library, I could not get my functions to return a value after an error was raised without a Resume command. Maybe I downloaded a different version of PB than everyone else, but I doubt it.
I know PureBasic is a little different with its onerror stuff than other languages, so you have to do it slightly differently. But i don't see how you are unable to do it like this

Code: Select all

        OnErrorGoto(?SkipLibrary)
        RaisedError = 1
        LibID = OpenLibrary(#PB_Any, DirectoryEntryName(DirID))
        
        RaisedError = 0
        If (LibID <> 0)
         ; deal with the library

          CloseLibrary(LibID)
        EndIf
        
        SkipLibrary:
          If (RaisedError <> 0)
            PrintN("  skipped " + Hex(Attributes) + " = " + LibraryName$)
          EndIf
A bit different than try/catch/finally in other languages, but this way worked for me in one of the rare situations that it was necessary. This code recovers from a fatal error during SO loading in linux with the latest 5.71 version of PureBasic on Neptune linux without the user noticing anything.

I agree that the standard try/catch/finally method in other languages feels more elegant to use.
webpage - discord chat links -> purebasic GPT4All
Dawgmann
User
User
Posts: 40
Joined: Wed Jul 17, 2019 5:32 pm

Re: Try/Catch/Finally error handling...

Post by Dawgmann »

Here is the exact code I was using to test (along with Danilo's "Try/Catch" macros). It's sloppy, but quick and dirty for testing...

Make sure to comment out either the call to the RunTry() procedure, or the call to the RunOnErr() procedure when testing. Do not run both procedures at the same time as the two methods should never be mixed. Additionally, when testing each procedure, you may comment out the call to the PokeS() procedure to see the different affects of what occurs.

- The Try/Catch error handler returns a value following an error, but does not raise the correct error number. This cannot work for me.
- The OnError() error handler raises the correct error number, but it does not allow the function to return a value to its caller. This (especially) cannot work for me, either. Also note that the label is executed twice when using OnErrorGoto(?ErrHndlr). However, the procedure correctly only executes once when using OnErrorCall(@DoErrHandlr()).

I would prefer to use the OnError() style of error handling over Try/Catch if I can figure out how to force my functions to return a value to their caller. So, if anyone can point out what I'm doing wrong here, your assistance will be greatly valued. However, it would also be nice if we can get the Try/Catch style ironed out as well. Someone else may prefer it over OnError().

Test Code
CompilerIf #PB_Compiler_Debugger
CompilerError "please disable debugger"
DisableDebugger
CompilerEndIf

Procedure DoErrHandlr()
MessageRequester("ShowMessage_OnError()", "Oops! An error occured here." + #CRLF$ + #CRLF$ + "Error Number: " + Str(ErrorCode())) ;Display the error code to user...
EndProcedure

Procedure.i ShowMessage_Try(Text.s)
Protected.i intRslt ;Retains the value to be returned by the function...

Try
MessageRequester("ShowMessage_Try()", Text)

PokeS(123, "The quick brown fox jumped over the lazy dog.") ;Purposely cause a stack error...

intRslt = 1000 ;Indicate the function successfully executed...
Catch
MessageRequester("ShowMessage_Try()", "Oops! An error occured here which should have returned the number [-1073741819] but returned the incorrect number of:" + #CRLF$ + #CRLF$ + "Error Number: " + Str(ErrorCode())) ;Display the error code to user...

intRslt = 2000 ;Indicate the function was not successful...
EndTry

MessageRequester("ShowMessage_Try()", "If you see this message, the command excuted correctly regardless of whether an error occurred.")

ProcedureReturn intRslt ;Return whether the function successfully executed...
EndProcedure

Procedure.i ShowMessage_OnErr(Text.s)
Protected.i intRslt ;Retains the value to be returned by the function...

OnErrorGoto(?ErrHndlr)
; OnErrorCall(@DoErrHandlr())

MessageRequester("ShowMessage_OnError()", Text)

PokeS(123, "The quick brown fox jumped over the lazy dog.") ;Purposely cause a stack error...

intRslt = 1000 ;Indicate the function successfully executed...

ProcedureReturn intRslt ;Return whether the function successfully executed...

ErrHndlr: ;THIS LABEL IS EXECUTED TWICE WHEN AN ERROR OCCURS...
MessageRequester("ShowMessage_OnError()", "Oops! An error occured here." + #CRLF$ + #CRLF$ + "Error Number: " + Str(ErrorCode())) ;Display the error code to user...

ProcedureReturn 2000 ;Return that the function was not successful...
EndProcedure

Procedure RunTry()
Protected.i intRslt ;Retains the execution result of the 'ShowMessage()' function...

intRslt = ShowMessage_Try("Hello, World!") ;Call the function to show the message...

If intRslt = 1000
MessageRequester("RunTry()", "The called function successfully returned a value of True to indicate no error occurred.")
ElseIf intRslt = 2000
MessageRequester("RunTry()", "The called function successfully returned a value of False to indicate an error did occur.")
Else
MessageRequester("RunTry()", "The called function did not return a value following an error. This is unacceptable.")
EndIf
EndProcedure

Procedure RunOnErr()
Protected.i intRslt ;Retains the execution result of the 'ShowMessage()' function...

intRslt = ShowMessage_OnErr("Hello, World!") ;Call the function to show the message...

If intRslt = 1000
MessageRequester("RunOnErr()", "The called function successfully returned a value of True to indicate no error occurred.")
ElseIf intRslt = 2000
MessageRequester("RunOnErr()", "The called function successfully returned a value of False to indicate an error did occur.")
Else
MessageRequester("RunOnErr()", "The called function did not return a value following an error. This is unacceptable.")
EndIf
EndProcedure

If OpenConsole() ;If a console window is successfully created - begin the program...
Define.i intRslt ;Retains the execution result of the 'ShowMessage()' function...

EnableGraphicalConsole(#True) ;Turn on graphical text mode...
ConsoleTitle("PureBasic: Console Test") ;Set the console windows's caption...

; RunTry() ;Test the Try/Catch error handling process...
RunOnErr() ;Test the OnError() error handling process...

CloseConsole() ;Close the console window...
EndIf

End ;Completely end program...
collectordave
Addict
Addict
Posts: 1309
Joined: Fri Aug 28, 2015 6:10 pm
Location: Portugal

Re: Try/Catch/Finally error handling...

Post by collectordave »

Try as I might I cannot get the difference between Try Catch and OnErrorgoto Catch:

When a FATAL error occurred it was just that FATAL.

To me it meant I could not trust that any return would go back to the calling procedure even if possible.

Can someone explain the difference?

CD
Any intelligent fool can make things bigger and more complex. It takes a touch of genius — and a lot of courage to move in the opposite direction.
Dawgmann
User
User
Posts: 40
Joined: Wed Jul 17, 2019 5:32 pm

Re: Try/Catch/Finally error handling...

Post by Dawgmann »

@collectordave
collectordave wrote:Try as I might I cannot get the difference between Try Catch and OnErrorgoto Catch:

When a FATAL error occurred it was just that FATAL.

To me it meant I could not trust that any return would go back to the calling procedure even if possible.

Can someone explain the difference?

CD
Well, actually, yes... other languages do successfully allow the erring function to return a value to the calling procedure. Example... C++/C#/Visual Basic/Object Pascal, etc.
Regardless of the ignorance of those who believe all apps should just simple exit after an error... even if the erring function simply returns a null or "Empty" value, very often this is a necessary requirement for the software to initiate security protocols in order to safely shut down the software. Some people's/group's data is worth more than the ignorance of unenlightened coders who can't see the forest for the stick in their eye.

Granted, these other languages are professional, enterprise-level languages rather than toy/hobbyist development systems. But while a lot of features are mere candy and add huge amounts of encumbering bloat to a language/development system, this particular feature is one of a few base requirements (along with event procedures which can pass parameters and enumerated data types) for any serious professional software development, especially when dealing with encrypted databases which hold sensitive data.
User avatar
skywalk
Addict
Addict
Posts: 3972
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: Try/Catch/Finally error handling...

Post by skywalk »

Can you simplify/elaborate your code examples with the Code tags on please?
And lower the philosophy discussion when approaching others for response.
As mentioned, the strain of a 'catch all' system is purely up to the coder in PureBasic.
Your app is no different from the multitudes created by users here.
It was suggested that you preclude iffy code with necessary checks to insure errors are trapped BEFORE they happen.
Instead, you prefer the compiler do that in the background.
A simplistic example, but you can extend this to function calls, lib calls, etc. :idea:

Code: Select all

If x / y  ;<-- Dangerous, requires error trapping.
  ;do something.
EndIf

Code: Select all

#mysmall1 = 1e-15
If x / (y + #mysmall1)  ;<-- Safe, no error trap required.
  ;do something.
EndIf
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
User avatar
NicTheQuick
Addict
Addict
Posts: 1224
Joined: Sun Jun 22, 2003 7:43 pm
Location: Germany, Saarbrücken
Contact:

Re: Try/Catch/Finally error handling...

Post by NicTheQuick »

skywalk wrote:

Code: Select all

#mysmall1 = 1e-15
If x / (y + #mysmall1)  ;<-- Safe, no error trap required.
  ;do something.
EndIf
It's also not safe if y = #mysmall1. :wink:
But fortunality floating point arithemtics allow dividing by zero. So it's not an error anymore.
The english grammar is freeware, you can use it freely - But it's not Open Source, i.e. you can not change it or publish it in altered way.
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

Re: Try/Catch/Finally error handling...

Post by Mijikai »

Pls...

Some black magic:

Code: Select all

Macro OnErrorResume(Label)
  !push rax rcx rdx rbx rbp rsi rdi
  OnErrorGoto(Label)
EndMacro

Procedure.i Dummy(Something.i)
  OnErrorResume(?ErrorHandler)
  PokeS(10, "Hello World")
  ProcedureReturn Something
  ErrorHandler:
  ProcedureReturn 404
EndProcedure

MessageRequester(#Null$,Str(Dummy(123)))
Dawgmann
User
User
Posts: 40
Joined: Wed Jul 17, 2019 5:32 pm

Re: Try/Catch/Finally error handling...

Post by Dawgmann »

@skywalk

That's the point...
I DO NOT rely on the compiler to catch errors for me. Why?

a. Compilers are created by humans and therefore, prone to errors. So, hoping a compiler or debugger will catch all run-time errors caused by a programmer's logic (or lack of it) is a dangerous idea. I don't want the compiler to handle them, which is why I want the function to be able to return a value to the calling method/event. Which part of me saying this over and over are you and others not grasping? Do I need to do sign language?

b. Some critical run-time errors which are caused by corrupted OS files or hardware generally will not exist on the development computer but can often come into play on and end-user's system.

In either case, not preemptively safe-guarding against such occurrences is completely irresponsible and should be shamed in programming circles, if not made illegal when developing software for money and allowing other people's expensive data to be reliant on one's ego and poor programming discipline.

"...lower the philosophy discussion when approaching others for response."

I will do so when those issuing response do the same and keep their programming to themselves. If they want to let the app quit immediately following an error, then let them do so to their heart's content. I don't try to change their minds or give them advice, as I am only concerned with what I do. However, in keeping with your own words, they probably shouldn't push their dangerous philosophy(ies) onto me because they can't grasp in their own limited cognition what it is I need.
Last edited by Dawgmann on Thu Sep 12, 2019 4:04 pm, edited 1 time in total.
Dawgmann
User
User
Posts: 40
Joined: Wed Jul 17, 2019 5:32 pm

Re: Try/Catch/Finally error handling...

Post by Dawgmann »

@Mijikai

And BOOM! Mijikai drops the mic and struts off the stage.

Thank you, Brother!.!.! This is exactly what I needed the whole time and error handling works as I need it.

You have won the internet today. You made it so simple, and without snide remarks. Others might come out of their mother's basement to take note of your style...
Last edited by Dawgmann on Thu Sep 12, 2019 4:16 pm, edited 1 time in total.
User avatar
skywalk
Addict
Addict
Posts: 3972
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: Try/Catch/Finally error handling...

Post by skywalk »

NicTheQuick wrote:
skywalk wrote:

Code: Select all

#mysmall1 = 1e-15
If x / (y + #mysmall1)  ;<-- Safe, no error trap required.
  ;do something.
EndIf
It's also not safe if y = #mysmall1. :wink:
But fortunality floating point arithemtics allow dividing by zero. So it's not an error anymore.
Haha, you are correct if y == -1e-15 exactly. But, that has not happened in my lifetime. And, I am not coding lunar missions...yet! :twisted:
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
User avatar
skywalk
Addict
Addict
Posts: 3972
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: Try/Catch/Finally error handling...

Post by skywalk »

Dawgmann wrote:@Mijikai

And BOOM! Mijikai drops the mic and struts off the stage.

Thank you, Brother!.!.! This is exactly what I needed the whole time and error handling works as I need it.

You have won the internet today. You made it so simple, and without snide remarks. Others might come out of their mother's basement to take note of your style...
Ok, I tried to help. You are at a level I dare not aspire. :?
Let me know when this app reports back. :lol:

Code: Select all

; Mijikai, https://www.purebasic.fr/english/viewtopic.php?f=3&t=73592&start=15
Macro OnErrorResume(Label)
  !push rax rcx rdx rbx rbp rsi rdi
  OnErrorGoto(Label)
EndMacro
Procedure.i Dummy(Something.i)
  OnErrorResume(?ErrorHandler)
  Protected.i x,y
  x = 1/y   ; FAIL
  PokeS(10, "Hello World")
  ProcedureReturn Something
  ErrorHandler:
  ProcedureReturn 404
EndProcedure
MessageRequester(#Null$,Str(Dummy(123)))
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
Post Reply