Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

[REBOL] Re: Error Handling

From: brett:codeconscious at: 22-Dec-2002 23:19

I wrote sometime ago:
> I don't think it would be too difficult to add a > try-except to REBOL. I suspect it would be possible to make it a mezzanine > too.
And Maarten's post of Ernie's HANDLE showed some it. Some very handy stuff too which made me think some more on error handling ideas. Here's a few variants that might be interesting. They are obviously exploratory ideas not long-time tested concepts/scripts. Not sure of the usefulness of them but here they are... Sorry about line-wrapping of my verbose function doco. ; 8<------------------------------------------------------ REBOL [ Title: "Error handling possibilities." Author: "Brett Handley" ] on-error: func [ {Tries to DO a block or if an error DO handler.} [catch] block [block!] handler "If handler is a block! then ERROR, RESULT, BLOCK and HANDLER will be bound." /local result error ] [ if error? set/any 'result try block [ if block? :handler [ error: disarm result bind handler 'result ] set/any 'result do handler ] get/any 'result ] any-success: func [ {Tries to DO each block of a series and returns the first value that is not an error.} [catch] block [any-block!] /local result ] [ result: none repeat expression block [ if not error? set/any 'result try expression [break] ] get/any 'result ] until-success: func [ {Tries to DO the block and will continue retrying until the evaluation completes without an error.} [catch] block [any-block!] delay [time! block! none!] "Delay time or expression to DO before trying again." /local result ] [ if time? delay [delay: does compose [wait (delay)]] result: none forever [ if not error? set/any 'result try block [break] do delay ] get/any 'result ] ; 8<------------------------------------------------------ ; EXAMPLES ; ON-ERROR ; A (smaller) variation on Ernie's HANDLE. It allows the ; handler block to return a value. ; The handler just eats the error on-error [1 / 0] [] ; The handler returns a value where the first block fails. on-error [1 / 0] none on-error [1 / 0] ["Success"] ; The handler re-raises the original exception. on-error [1 / 0] [ print "do something important." result ] ; The handler has access to the disarmed error and ; Reinterprets math errors into a user error, other ; errors are just re-raised. A function is used here ; to demonstrate both cases. test-func: func [code] [ on-error code [ either error/type = 'math [ make error! "You shoulda saw that coming!" ] [result] ] ] test-func [Print "math error" 1 / 0] test-func [Print "bad arg type" read [asdfjkl--lksdfkl]] ; ANY-SUCCESS ; Try a few things - one of them should work... any-success [ [1 / 0] [read [asdfjkl--lksdfkl]] ["Success"] ] ; UNTIL-SUCCESS ; A simple delay, until finally success. k: 0 until-success [ print "trying..." if lesser? k: k + 1 4 [1 / 0] "Success!" ] 00:00:01 ; A complex delay. ; Breaking from the delay block returns the last error. k: 0 until-success [print "Trying..." 1 / 0] [ if greater? k: k + 1 4 [break] wait 00:00:01 ]