1. exception handler
- Posted by Robert Craig <rds at RapidEuphoria.com> Aug 24, 2004
- 531 views
I'm ready to implement the global exception handler concept. This will give your program a chance to take some action when the Euphoria interpreter (or less common - translated code) detects a run-time error. In 2.5 your program is completely parsed (compiled) before any execution begins, so there isn't much value in being able to react to compile-time errors. The implementation of this thing probably won't be difficult, but I want to get the language design right. I'm assuming the following: * using routine id's you can specify one or more routines to receive control when a run-time error occurs. Allowing more than one routine would be useful for library writers who might want to specify a routine to clean up resources, locked files etc. for their library, independent of what the application writer wants to do in his own code. * you can't resume execution. Once the crash routine(s) have finished, the program will terminate. * by default, the most recently specified crash routine will be executed first, working back to the first routine specified. Maybe there will be a way to change this order. * your routine(s) will be called after the normal ex.err dump occurs, so I guess your routine(s) could look at ex.err in deciding what to do. If a second ex.err is necessary while running your routines, I'll use a different file name, like ex2.err or something. If your routine(s) themselves crash, there won't be any more calls to crash routines. That's the end. The possible uses for this have been discussed before. e.g. - cleaning up files and resources that won't automatically be cleaned up when the interpreter terminates your program. - the "classic" example of an editor that could save the user's edit buffer to disk before dying. - a server program that could send an e-mail notification with debug info (such as ex.err) when it dies unexpectedly in the middle of the night. - I suppose a program could effectively restart itself and keep going if a crash routine were set up that way. Regards, Rob Craig Rapid Deployment Software http://www.RapidEuphoria.com
2. Re: exception handler
- Posted by Derek Parnell <ddparnell at bigpond.com> Aug 24, 2004
- 461 views
Robert Craig wrote: > > I'm ready to implement the global exception handler concept. YEAH!!! (First recorded suggestion in Sep 1999 by Pete Eberlein) > This will give your program a chance to take some action > when the Euphoria interpreter (or less common - translated code) > detects a run-time error. In 2.5 your program is completely parsed > (compiled) before any execution begins, so there isn't much > value in being able to react to compile-time errors. And this means that forward referencing is possible too, of course. But that's another battle. > The implementation of this thing probably won't be difficult, > but I want to get the language design right. Excellent. Fully support that approach. > I'm assuming the following: > > * using routine id's you can specify one or more routines > to receive control when a run-time error occurs. Allowing > more than one routine would be useful for library writers > who might want to specify a routine to clean up resources, > locked files etc. for their library, independent of what > the application writer wants to do in his own code. Yes. > * you can't resume execution. Once the crash routine(s) > have finished, the program will terminate. Probably. However some 'crashes' may be recoverable. Divide by zero using input from an operator - you ask the operator for a different value. > * by default, the most recently specified crash routine will > be executed first, working back to the first routine > specified. Maybe there will be a way to change this order. Yes. > * your routine(s) will be called after the normal ex.err dump > occurs, so I guess your routine(s) could look at ex.err > in deciding what to do. If a second ex.err is necessary > while running your routines, I'll use a different file name, > like ex2.err or something. If your routine(s) themselves crash, > there won't be any more calls to crash routines. That's the end. Usable. But a formal EU-defined error data passed to the routine would be more useful - detailing reason for crash, file name, line number, calling stack trace(?). > The possible uses for this have been discussed before. > e.g. > - cleaning up files and resources that won't automatically be > cleaned up when the interpreter terminates your program. > > - the "classic" example of an editor that could save the > user's edit buffer to disk before dying. > > - a server program that could send an e-mail notification > with debug info (such as ex.err) when it dies unexpectedly > in the middle of the night. > > - I suppose a program could effectively restart itself > and keep going if a crash routine were set up that way. > > Regards, > Rob Craig > Rapid Deployment Software Thanks Robert. But will this significantly slow down the delivery of 2.5? I know this enhancement is essential for quality commercial software development, but maybe it can be added to 2.5.1, during which time we can shake out any issues with the whatever is currently in 2.5? -- Derek Parnell Melbourne, Australia
3. Re: exception handler
- Posted by Patrick Barnes <mrtrick at gmail.com> Aug 24, 2004
- 461 views
On Mon, 23 Aug 2004 18:35:51 -0700, Robert Craig <guest at rapideuphoria.com> wrote: > I'm ready to implement the global exception handler concept. Sound mostly good... I'm not going to get into the "but why can't it do this" argument, especially asking why it can't recover to a certain point, and continue operating without a crash. I'd just ask that you implement it in such a way that it can be extended, later in the piece.... Now, critique: If it's a handler, shouldn't it be able to continue (Definition)? Maybe it should have a different name if it can't resume.... crash cleanup? > * using routine id's you can specify one or more routines > to receive control when a run-time error occurs. Allowing > more than one routine would be useful for library writers > who might want to specify a routine to clean up resources, > locked files etc. for their library, independent of what > the application writer wants to do in his own code. How would you define which cleanup routines handle which code? File level, routine level? There isn't much delineation of libraries or packages in Euphoria at the moment... it's only a file-level thing. One thing, is - what stops the programmer from trying to continue indefinitely in the cleanup routine(s)? So, what arguments are the cleanup routines going to take? What sort of information will a cleanup routine need? Seeing as routine_id is such a generic concept, and seeing as there is a possible problem with cleanup routines continuing too long, maybe it should have it's own syntax? > * you can't resume execution. Once the crash routine(s) > have finished, the program will terminate. Hmmm, makes things simpler, but it's limiting - all the languages I've seen with exceptions (catch-throw) allow continuing operation. I guess you have your reasons - but some cleanup is better than no cleanup. If it's extensible, so that if you change your mind down the track change is easier - that'd be a plus. > * by default, the most recently specified crash routine will > be executed first, working back to the first routine > specified. Maybe there will be a way to change this order. That's fine > * your routine(s) will be called after the normal ex.err dump > occurs, so I guess your routine(s) could look at ex.err > in deciding what to do. If a second ex.err is necessary > while running your routines, I'll use a different file name, > like ex2.err or something. If your routine(s) themselves crash, > there won't be any more calls to crash routines. That's the end. well ex stands for execution, I guess.... how about clean.err? > The possible uses for this have been discussed before. > e.g. > - cleaning up files and resources that won't automatically be > cleaned up when the interpreter terminates your program. Yup, sounds good > - the "classic" example of an editor that could save the > user's edit buffer to disk before dying. Yup, sounds good - or saves the preferences back to disk <-- I want this - damn you MEdit and your scroll wheel crashes. > - a server program that could send an e-mail notification > with debug info (such as ex.err) when it dies unexpectedly > in the middle of the night. Yup sounds good. > - I suppose a program could effectively restart itself > and keep going if a crash routine were set up that way. Now, what are the limits of the cleanup routine? I ask again, what stops a programmer trying to turn the cleanup routine into a continue-type handler? P.S. How about setting up a structured forum, that could tabulate these ideas effectively, as well as for any more decisions you want our input on. You could make it a programming competition to develop one -- MrTrick
4. Re: exception handler
- Posted by irv mullins <irvm at ellijay.com> Aug 24, 2004
- 444 views
Patrick Barnes wrote: > If it's a handler, shouldn't it be able to continue (Definition)? > Maybe it should have a different name if it can't resume.... crash > cleanup? My thoughts exactly. It isn't an exception handler if it can't handle exceptions. Maybe "airbag" would be more appropriate (when you crash, it does less damage;) Anyway, as has been mentioned before, the type() routine could be extended in such a way as to allow handling many errors, simply by returning to the top of a program block marked by a 'catch' or 'try' keyword.
type file(object x) if x =-1 then msgbox("Cannot open file") return FALSE else return TRUE end type file fn object fname try puts(1,"Enter a file name here:") fname = gets(0) fn = open(fname,"r") end try
Irv
5. Re: exception handler
- Posted by CoJaBo <cojabo at suscom.net> Aug 24, 2004
- 450 views
Robert Craig wrote: > > I'm ready to implement the global exception handler concept. > This will give your program a chance to take some action > when the Euphoria interpreter (or less common - translated code) > detects a run-time error. In 2.5 your program is completely parsed > (compiled) before any execution begins, so there isn't much > value in being able to react to compile-time errors. > The implementation of this thing probably won't be difficult, > but I want to get the language design right. > > I'm assuming the following: > > * using routine id's you can specify one or more routines > to receive control when a run-time error occurs. Allowing > more than one routine would be useful for library writers > who might want to specify a routine to clean up resources, > locked files etc. for their library, independent of what > the application writer wants to do in his own code. The crash routine shyould recieve an error code(like EC_DIV_BY_0), the error message(like "attempt to divide by 0") > > * you can't resume execution. Once the crash routine(s) > have finished, the program will terminate. There should be a way to resume execution(like a crash routine returning a certain value, for example after asking the user whether to try to continue) This should only be able to happen with the first crash routine > > * by default, the most recently specified crash routine will > be executed first, working back to the first routine > specified. Maybe there will be a way to change this order. > > * your routine(s) will be called after the normal ex.err dump > occurs, so I guess your routine(s) could look at ex.err > in deciding what to do. If a second ex.err is necessary > while running your routines, I'll use a different file name, > like ex2.err or something. If your routine(s) themselves crash, > there won't be any more calls to crash routines. That's the end. If a crash routine itself crashes, Euphoria should write the error to ex_#.err (or if another neme was set, like crash.abc, to crash_#.abc) and continue with the next crash routine. This would make sure every crash routine runs. > > The possible uses for this have been discussed before. > e.g. > - cleaning up files and resources that won't automatically be > cleaned up when the interpreter terminates your program. > > - the "classic" example of an editor that could save the > user's edit buffer to disk before dying. This woulld be VERY helpful! Now if only Euphoria could prevent data loss caused by other problems (like power outages,computer catching fire, cats unplugging the computer)... > > - a server program that could send an e-mail notification > with debug info (such as ex.err) when it dies unexpectedly > in the middle of the night. > > - I suppose a program could effectively restart itself > and keep going if a crash routine were set up that way. This would definatly be useful for my webserver program. > > Regards, > Rob Craig > Rapid Deployment Software > <a href="http://www.RapidEuphoria.com">http://www.RapidEuphoria.com</a> >
6. Re: exception handler
- Posted by irv mullins <irvm at ellijay.com> Aug 24, 2004
- 458 views
irv mullins wrote: > Anyway, as has been mentioned before, the type() routine could be > extended in such a way as to allow handling many errors, simply by > returning to the top of a program block marked by a 'catch' or > 'try' keyword. > > }}} <eucode> > type file(object x) > if x =-1 then > msgbox("Cannot open file") > return FALSE > else return TRUE > end type > > file fn > object fname > > try > puts(1,"Enter a file name here:") > fname = gets(0) > fn = open(fname,"r") > end try > </eucode> {{{ To follow up, I think this could be added without breaking any code. As it stands, if the type() check fails, the program quits. If it succeeds, then the assignment is made and program flow continues. A new keyword, "try", would patch into type()'s failure routine, and cause execution to resume at the top of the "try" loop. If there was no "try" in effect, then the type() check would act just as it does now, either make a valid assignment, or crash. Irv
7. Re: exception handler
- Posted by Pete Lomax <petelomax at blueyonder.co.uk> Aug 24, 2004
- 469 views
On Mon, 23 Aug 2004 18:35:51 -0700, Robert Craig <guest at RapidEuphoria.com> wrote: >I'm ready to implement the global exception handler concept. I'll tell you what I know about x86 support for exception handlers, of which there are two types: A 'final exception handler' has only one instance, and if you attempt to define a second, it simply overwrites all evidence that the previous handler ever existed. While it is technically possible to resume from this type of handler, that is not why it exists. The other type is 'structured exception handling', which allows nested try/catch blocks and is designed to allow a program to recover and continue, and allow 'throw' to act as a sort of goto statement. The main requirement is to define a 'safe place' for processing to resume, since you cannot eg resume on a divide-by-zero error - if it was 1/X then you _might_ be able to set X non-zero, but if F() has returned zero in 1/F() there is no 'safe place' to resume. This type of handler is strongly tied to the call/return stack, and will automatically reset the stack pointer when handling an exception from a nested call, etc. It sounds to me that you might want to implement the equivalent of a final exception handler first and leave structured/resuming for later. >This will give your program a chance to take some action >when the Euphoria interpreter (or less common - translated code) >detects a run-time error. In 2.5 your program is completely parsed >(compiled) before any execution begins, so there isn't much >value in being able to react to compile-time errors. >The implementation of this thing probably won't be difficult, >but I want to get the language design right. > >I'm assuming the following: > > * using routine id's you can specify one or more routines > to receive control when a run-time error occurs. Allowing > more than one routine would be useful for library writers > who might want to specify a routine to clean up resources, > locked files etc. for their library, independent of what > the application writer wants to do in his own code. > While you can use routine_id for the final exception handler, I think you should use try... catch... end try blocks, where the end try statement defines the 'safe place' if the handler attempts to continue execution. > * you can't resume execution. Once the crash routine(s) > have finished, the program will terminate. > As above, that is what a final exception handler should do. > * by default, the most recently specified crash routine will > be executed first, working back to the first routine > specified. Maybe there will be a way to change this order. > > * your routine(s) will be called after the normal ex.err dump OK, no real preference here. > occurs, so I guess your routine(s) could look at ex.err Oh dear. I guess that means we'll need a library specifically for library exception handlers... > in deciding what to do. If a second ex.err is necessary > while running your routines, I'll use a different file name, > like ex2.err or something. If your routine(s) themselves crash, > there won't be any more calls to crash routines. That's the end. I vote against that. If the program's exception handler crashes, that should be left in ex.err and be the first thing the programmer has to fix. The original problem will have to be reproduced and the ex.err for that recreated. Besides, after fixing one, the line numbers for the other problem may be all wrong. You should probably zero the internal copy of that routine_id before calling it, to reduce the chance of an infinite loop. > >The possible uses for this have been discussed before. >e.g. > - cleaning up files and resources that won't automatically be > cleaned up when the interpreter terminates your program. > > - the "classic" example of an editor that could save the > user's edit buffer to disk before dying. > > - a server program that could send an e-mail notification > with debug info (such as ex.err) when it dies unexpectedly > in the middle of the night. > > - I suppose a program could effectively restart itself > and keep going if a crash routine were set up that way. How? > >Regards, > Rob Craig > Rapid Deployment Software > http://www.RapidEuphoria.com > > > >
8. Re: exception handler
- Posted by Pete Lomax <petelomax at blueyonder.co.uk> Aug 24, 2004
- 458 views
- Last edited Aug 25, 2004
On Tue, 24 Aug 2004 08:48:04 -0700, irv mullins <guest at RapidEuphoria.com> wrote: Why restrict this to types? > >A new keyword, "try", would patch into type()'s failure routine, >and cause execution to resume at the top of the "try" loop. > It should be the *end* of the try block, or some explicit code as in a try/catch/end try statement. This makes it much clearer where to put code to check what failed, eg: try fail=1 open(... fail=2 getc(... fail=3 close(... catch if fail=1 then elsif fail=2 then end try Of course if you use three try blocks, you don't need a fail variable. If you want it to loop, add a loop around the try block(s). Pete PS The above is structured exception handling, and as I said in my other post, Rob should get a simpler final exception handler working first.
9. Re: exception handler
- Posted by irv mullins <irvm at ellijay.com> Aug 24, 2004
- 472 views
- Last edited Aug 25, 2004
Pete Lomax wrote: > It should be the *end* of the try block, or some explicit code as in a > try/catch/end try statement. This makes it much clearer where to put > code to check what failed, eg: > > try > fail=1 > open(... > fail=2 > getc(... > fail=3 > close(... > catch > if fail=1 then > elsif fail=2 then > end try > > Of course if you use three try blocks, you don't need a fail variable. > If you want it to loop, add a loop around the try block(s). > > Pete > PS The above is structured exception handling, and as I said in my > other post, Rob should get a simpler final exception handler working > first. I see it's structured. I can also see there's no way to go back and try again if it fails. Suppose the open(... fails. That would be fail=1, right? So what does the "if fail=1 then" do? Go back and try again? If so, How? Irv
10. Re: exception handler
- Posted by Matt Lewis <matthewwalkerlewis at yahoo.com> Aug 24, 2004
- 462 views
- Last edited Aug 25, 2004
irv mullins wrote: > > Pete Lomax wrote: > > > It should be the *end* of the try block, or some explicit code as in a > > try/catch/end try statement. This makes it much clearer where to put > > code to check what failed, eg: > > > > try > > fail=1 > > open(... > > fail=2 > > getc(... > > fail=3 > > close(... > > catch > > if fail=1 then > > elsif fail=2 then > > end try > > > > Of course if you use three try blocks, you don't need a fail variable. > > If you want it to loop, add a loop around the try block(s). > > > > Pete > > PS The above is structured exception handling, and as I said in my > > other post, Rob should get a simpler final exception handler working > > first. > > I see it's structured. I can also see there's no way to go back and > try again if it fails. Suppose the open(... fails. > That would be fail=1, right? So what does the "if fail=1 then" do? > Go back and try again? If so, How? I think that there's no way to go back here because it's a simple example, similar your example using types. Pete's idea is just an extension of this, but it provides for an automatic way to handle the exception, rather than simply continuing execution, and forcing you to set a flag or some other manual thing. Your example tells the user that the file is bad, but you don't provide for dealing with a bad file handle. It would have to be manually checked, as opposed to returning from the procedure after notification, or whatever seems the right way for the app to handle the exception. My take on structured exception handling is that it's really just a formal and 'official' way to validate things. I guess the benefit is that the validation can be more easily modularized and automated (i.e., through type checking). I'm not very savvy with regards to this topic, but what would/should happen in this case:
type file( object o ) if not integer(o) or o = -1 then return 0 end if return 1 end type file fn procedure foo() -- for simplicity, suppose we try to open a -- bad file, causing fn = -1 fn = open("bad file name", "r" ) end procedure procedure bar() try foo() catch return end try ? get(fn) close(fn) end procedure bar()
Would the try block apply to exceptions in foo()? What if foo() had its own try block, and caught the exception, but can't fix it--in other words, we have a bad result, and we know that the result of foo() is depended upon later? Do we need to explicitly throw() an exception up the chain in order for bar() to know that there was an exception? What happens to fn? Does it stay unassigned--or if previously assigned, does it keep its old value? I know a lot about this topic has been discussed before, but I had a tough time staying awake through the discussions. :( Matt Lewis
11. Re: exception handler
- Posted by Terry Constant <EUforum at terryconstant.com> Aug 24, 2004
- 467 views
- Last edited Aug 25, 2004
Craig wrote: "your routine(s) will be called after the normal ex.err dump occurs, so I guess your routine(s) could look at ex.err in deciding what to do. If a second ex.err is necessary while running your routines, I'll use a different file name, like ex2.err or something. If your routine(s) themselves crash, there won't be any more calls to crash routines. That's the end." Parnell wrote: "Usable. But a formal EU-defined error data passed to the routine would be more useful - detailing reason for crash, file name, line number, calling stack trace(?)." Rob, I am glad to see that you are implementing improved exception handling. I will be happy to get most anything you provide (even while I have my personal preferences.) So, let me make just two comments. 1. As to filename "ex2.err", use something more mnemonic such as: except.err cleanup.err exclean.err exuser.err or whatever mnemonic you choose. 2. I agree with Parnell about the utility of detailed error data being passed to the routine. In addition to Parnell's suggestions, I would like to receive the routine name also, using something like "global", "local" or "top" or whatever is best for statements not inside defined routines. Terry Constant
12. Re: exception handler
- Posted by irv mullins <irvm at ellijay.com> Aug 24, 2004
- 462 views
- Last edited Aug 25, 2004
Matt Lewis wrote: > I know a lot about this topic has been discussed before, but I had a tough > time staying awake through the discussions. :( I think the easiest thing to do is look at how exceptions are handled in other languages, run some tests, and then just copy the method which gives the best results. Which I would define as not crashing if there is an alternative. Irv
13. Re: exception handler
- Posted by Pete Lomax <petelomax at blueyonder.co.uk> Aug 24, 2004
- 457 views
- Last edited Aug 25, 2004
On Tue, 24 Aug 2004 13:55:16 -0700, irv mullins <guest at RapidEuphoria.com> wrote: >Pete Lomax wrote: > >> It should be the *end* of the try block, or some explicit code as in a >I see it's structured. Erm, be careful what you mean here; structured exception handling is designed to work well with structured (IE *subroutined*) code, not necessarily exception handling which is itself structured. Think of something nasty happening miles away, say mid-way through pushing one of several parameters. Of course I plan/hope for both. > I can also see there's no way to go back and >try again if it fails. Suppose the open(... fails. >That would be fail=1, right? So what does the "if fail=1 then" do? >Go back and try again? If so, How? fail=9 while fail do try... end while OK, you may have a point, it would be annoying to have to reset a control var in *every* case. That said, I *will* sacrifice a few extra lines of code to make the control flow clearer, though. What I would hate to see is a design whereby we have: try <code to handle the failure cases> <code which might fail> end try because that is harder to follow. OTOH, thinking about it out loud, I guess I don't really have a problem with eg: catch overflow: ... divide_by_zero: ... in <code> end catch or, indeed: catch while ... (assuming: if "while" then "exit" jumps to the end catch no exit resumes at "in" (bit like "else") "end catch" loops else (just "catch", no "while") after catch, control resumes at "end catch" "exit" is illegal "end catch" does not loop end if in both cases, of course, there is an implicit jump to the "in" part at the start of the block. ) Still upside-down, but possibly bearable, Actually, I quite like that... Pete
14. Re: exception handler
- Posted by Pete Lomax <petelomax at blueyonder.co.uk> Aug 25, 2004
- 469 views
On Tue, 24 Aug 2004 13:55:15 -0700, Matt Lewis <guest at RapidEuphoria.com> wrote: <snip> >Would the try block apply to exceptions in foo()? Yes, but without a 'safe point' explicitly defined in foo(), it cannot possibly resume anywhere in that code; it would resume either somewhere in bar() or the line following where bar() was invoked. > What if foo() had >its own try block, and caught the exception, but can't fix it--in other >words, we have a bad result, and we know that the result of foo() is >depended upon later? Do we need to explicitly throw() an exception up >the chain in order for bar() to know that there was an exception? No, see below. >What happens to fn? Nothing. >Does it stay unassigned--or if previously assigned, does >it keep its old value? Yes. If you need to know that you have just caught and handled an exception, then of course you just define and set a flag like you normally would. Also, if you catch an exception in a function, then that function must/might have to return the "unassigned" value (#40000000 in posetf, I believe #A0000000 in Euphoria, but I could be wrong), triggering another (higher level, so it won't loop forever) exception if that value is ever used. Actually, I think someone (wolf?) posted some code for this (well the simpler single final exception handler) involving calling the win32 setFinalExceptionHandler routine with a callback routine?? Did anyone get something similar working on Linux/dos? Pete
15. Re: exception handler
- Posted by Pete Lomax <petelomax at blueyonder.co.uk> Aug 25, 2004
- 445 views
On Wed, 25 Aug 2004 01:34:25 +0100, Pete Lomax <petelomax at blueyonder.co.uk> wrote: >Actually, I think someone (wolf?) posted some code for this Oh dear, it was in fact someone called Matthew Lewis, who, correct me if I am wrong, I was just replying to! Oops, Pete PS it is actually SetUnhandledExceptionFilter, the relevant posts are http://www.listfilter.com/cgi-bin/esearch.exu?keywords=setunhandledexceptionfilter
16. Re: exception handler
- Posted by Pete Lomax <petelomax at blueyonder.co.uk> Aug 26, 2004
- 451 views
On Wed, 25 Aug 2004 17:36:51 -0700, irv mullins <guest at RapidEuphoria.com> wrote: >I suggest you call it "improved crash handling", Or how about "fatal error cleanup" Pete