No announcement yet.

on error trouble

  • Filter
  • Time
  • Show
Clear All
new posts

  • on error trouble

    Hi people,

    i hope someone can help me with the following:
    i have a problem with using "on error goto". when an error occurs
    the errortrap works nicely and the correct actions are taken.
    however, when the error occurs again in the same run, the program
    aborts with the default PB error stuff and does not go through the
    "on error goto" statement. as far as i know i only have to issue
    the "on error goto" statement once. i wrote some pseudo code to
    hopefully clarify my program flow a bit.

    ' main

    on error goto crashexit
    call menu

    ' subs

    sub menu
    exit far at synterr1
    call actions
    end sub

    sub actions
    ' this is where an error occurs
    end sub

    ' errorstuff

    print "error"
    exit far

    So, if someone can tell me more about why the errortrap only works
    once, i'd be much obliged.




  • #2
    Instead of exit far use RESUME synterr1



    • #3
      Look at the difference between the below and your source, OK?

      10 ' Program starts here - for practical purposes leave as header content
           ' For practical purposes the error handling in PowerBASIC seems
           ' restricted to NUMERIC lables.  You can direct things to other
           ' than that, but the locations are still internally bound, it
           ' seems ... to NUMERIC line lables.  Thus you have to use them
           ' everywhere you wish to mark an error location, or...   You
           ' can create your own custom error mark location variahle
           ' and increment the location of it to do the same if you are
           ' intending to cross port the source to, say, C/C++...
           ' main
           MyERL& = 100 ' Private error marker
           ON ERROR GOTO 10000 ' Not really crashexit
           ' You'll likely benefit BIG TIME if you use
           ' a numeric line lable format for critical
           ' locations off in SUBS when you start
           ' nesting them like you are and do that
           ' in different UNITS or LIBRARIES as well!
           ' It makes a MUCH easier job of tracing errors.
           EXIT FAR AT 10000 '   Not really crashexit
           CALL MENU
      ' subs
      SUB MENU
           ' Wise thing to do is leave a hard
           ' numeric lable in SUB to mark it
           MyERL& = 2000 ' Private error marker
                 CALL ACTIONS
            EMD SUN
            ' Wise thing to do is leave a hard
            ' numeric lable in SUB to mark it
            MyERL& = 3000 ' Private error marker
            ' this is where an error occurs
            END SUB
            ' errorstuff all begins here
      10000 ' We use a numeric line lable with
            ' EXIT FAR as well
            MyERL& = 10000 ' Private error marker
            PRINT "error"
            ErrorLine& = ERL
            ErrorType& = ERR
            PRINT "error was "; ErrorType&; " at line "; ErrorLine&
            ' Or privately we can use
            PRINT "error was "; ErrorType&; " at location "; MyERL&
            ' We also need a RESUME statement
            ' which orchestrates the recovery
            ' and clears the error handling!
            IF ERL = 2000 OR _
             ERL = 3000 THEN
               RESUME 100
            END IF
            ' Which could take the form of
            ' RESUME Mainline
            ' one supposes!
            ' The point is that we have to
            ' use RESUME to get to play again!
            IF MyERL& = 2000 OR _
             MyERL& = 3000 THEN
               RESUME 100
            END IF
            ' It also can be RESUME NEXT
            ' but learn the details before use.
            ' but learn the details before use.
            ' Otherwise we will wind up here
              and SOMETHING will need to happen
              as we are standing at the cliff edge!
            ' Maybe it is just .. BON VOYAAGE and
            ' Here we are with a broken heart!
            ' We've popped our last pill and ..
            '   the truck won't start!

      Mike Luther
      [email protected]

      [This message has been edited by Mike Luther (edited December 15, 2002).]
      Mike Luther
      [email protected]


      • #4
        Gee mike, thanx for this wonderful explanation. now that i think of
        it, Basic is actually way to difficult for me, being stupid and all.
        so if it's all the same to you i'll discard your prose and
        pick up where i left off with Ken and Barby.

        p.s: i said -pseudo- code, look it up.

        and thanx to Jose.



        • #5
          Sorry Mike, lost my cool there for a minute.
          i've been trying some more things, including the tip Jose
          gave me, but that won't work. i have several subs, each with their
          own "exit far at" statement, so a "resume label:" won't work.
          obviously, if i use a "run" statement at the point where i have
          the "exit far" thing work fine. i just don't consider that to be
          clean programming.
          the only other thing i can think of i do the error trapping
          locally, a lot of work. so, i'm lost here. tips?




          • #6
            Firstly, thank you for apologizing Tom... Mike took a lot of time to help you by way of example, and such a response could easily discourage further assistance from the users that visit here.

            Anyway, to answer your question:

            Error trapping is disabled at the point an error occurs and the error trap starts running (to avoid circular execution if an error occurs within the trap), and reenabled when a RESUME statement is executed.

            If your error handler is terminating with an EXIT FAR, then error trapping will remain disabled.

            The solution is to RESUME to a label that is followed by an EXIT FAR statement, thus:
             EXIT FAR AT Terminate
             CALL TheSub
             PRINT "Termination sequence 5..4..3..2..Boom!"
            SUB TheSub()
             ON LOCAL ERROR GOTO TheTrap
             PRINT "Howdy do!"
             ERROR 9 ' oh ho!
             PRINT "Error 9....?"
             EXIT SUB
             PRINT "Error Trap detected an error #" ERR
             RESUME TheTrapHasEnded ' error trapping enabled again
             EXIT FAR
            END SUB

            PowerBASIC Support
            mailto:[email protected][email protected]</A>
            mailto:[email protected]


            • #7
              No problem at all with even the first reply Tom and Lance. If I can
              survive Fight-O-Net since Tom Jennings first released FIDO and I
              actually have a copy of it, I'm worse than Tom!

              One of the reasons I posted the way I did was to try to evoke exactly
              what you posted for us Lance. And I actually got what I was hoping
              for; an example of the second use of EXIT FAR in the SUB, grin!

              Now... teach me some more here, though, please. I think it was Bob Zale
              himself who over all this long ago, made the remark that, in practice,
              about the only errors you really can handle from which you can recover
              in user mode, are file and I/O errors. Thus, the main reason we use
              an ON LOCAL ERROR GOTO instance of all this in a SUB is to coordinate
              how to handle them in that SUB, with the idea that what doesn't get caught
              in what may even be a complex decision tree in that SUB, will result in
              a return to the MAIN code. Which ... can also be from a SUB which is
              in a UNIT (even within a PB Library of them!), or even from nested such
              CALLS from MAIN to UNIT to other UNIT as well.

              As I vizualize all this, the use of EXIT FAR in a SUB does force an exit
              from that sub clean, and RESUME in it restores error handing.

              But, if for example, as common practice, we use a decision tree in the
              LOCAL error handling, things get complicated. Suppose that we have a
              file I/O error which results from no such file when that SUB is called.
              Maybe it is there, but the LAN isn't up and the LAN server is where that
              desired file is located. Having the file actually missing and the LAN
              server still up may be a far different thing than the file 'missing'
              because the path is bogus. Other I/O errors can be postulated which
              offer all kinds of similar decision needs. So you may decide that the
              'fix' and the RESUME location are, for a given ERR and ERL, supposed
              to go INSIDE the SUB in some cases. But you also may have a global
              error handler in MAIN which has to make complex decisions about even
              the actual program exit, and how to clean up before you do that, if
              certain other errors not just like the example, are found.

              As I understand all this, the SECOND use of EXIT FAR, can contaminate
              the proper collapse of a nested error romp back the the master file
              error handling code in MAIN, and the use of a RESUME can't be done,
              in this case, until even more error analysis is made to keep the MAIN
              code from collapsing the whole boat.

              Many of my programs, for instance, may use all available standard 20
              file handles at the same time, locally. and server-wide, many of which
              are in shared read/write instances by many other users on the LAN.
              These *MUST* collapse in proper closes if something blows up in the deep
              nested SUB's. And the only way to really avoid code bloat is to use
              common other SUB's to do this which may be bound up in MAIN to keep from
              going nuts in a big project.

              ERROR 9 which you so nicely used in your example is, to me, a perfect
              case in point. If it occurs from a 'problem' in a UDT used as a either
              a parameter passed or PUBLIC structure, down in the SUB, and may not
              get handled exactly correctly in the middle of file I/O, or from
              stack corruption associated with it, don't we really lose all of the
              identity and all hope to globally handle it back in MAIN with the LOCAL
              use of EXIT FAR?

              Prose time!

              That original quote was slightly adapted from a locally famous old
              restroom tidbit in the old now gone Windmill Restaraunt men's room in
              Fairfield, Texas back in 1975! The pronoun was changed to fit the humor
              here, but the lines are real.

              In hopes you'd do EXACTLY what you did for helping here Lance, I saved
              the next bit of restroom humor for evoking what I hoped to get as another
              beautiful lesson from you next, Lance!

              Below those lines about belt high on the right side of the stall, someone
              else had written:

              "If your pills were any good,
              you could push the truck home!"

              Now teach us how to make sure we can push the truck home even with the
              most complex of errors way down in nested SUBS, including the issue of
              ERROR 9 from UDT issues as well carried into them?

              That without getting to Alice's brownies, please ..

              "One pill makes you smaller.
              One pill makes you tall.
              And the ones that Mommy gives you,
              Don't do any good at all!"

              GDRFC ..

              If you do, I'll post the final humor bit for which the place
              gets chuckles from all us old Alligator Gar's round here!

              Mike Luther
              [email protected]
              Mike Luther
              [email protected]


              • #8
                Error trapping is a tool that must be carefully designed into your app to work within the design constraints of your code.

                Retrofitting good error handling is often problematic since a good implementation should be designed into the app at the start of coding, rather than at the end.

                ie, the use of a "structured" approach to programming is key to success, and differentiates the novice from the professional.

                An EXIT FAR handler can be very useful, but if your design precludes its use then eoither adapt your design, or use more generic methods of returning through the call stack (ie, by returning a "user defined" error value which the calling code uses to determine whether the app should proceed or exit up one more level. For this reason I rarely use SUB's because I return generally return success/fail codes as FUNCTION result values. As an aside, this is generally how Windows API functions work too, so the habit is a good one to get into if you intend to move to the Windows realm.

                In summary, the basic rule of error trapping is that an ON ERROR error handler must finish with a RESUME statement. What you do after the RESUME is up to you.

                PS, I can't follow the folowing statement in your message:
                As I understand all this, the SECOND use of EXIT FAR, can contaminate
                the proper collapse of a nested error romp back the the master file
                error handling code in MAIN, and the use of a RESUME can't be done,
                in this case, until even more error analysis is made to keep the MAIN
                code from collapsing the whole boat.
                Can you please elaborate, and possible provide an example (even pseudocode will be fine).


                PowerBASIC Support
                mailto:[email protected][email protected]</A>
                mailto:[email protected]