From: Eckhard L. <ec...@we...> - 2006-11-02 13:34:35
|
> -----Urspr=FCngliche Nachricht----- > Von: Lars Hellstr=F6m <Lar...@re...> > Gesendet: 01.11.06 21:10:29 > An: tcl...@li... > Betreff: Re: [TCLCORE] TIP #290: Registration of Custom Error Handler Sc= ripts > 2006-11-01 kl. 15.02 skrev Eckhard Lehmann: > > This TIP proposes the possibility to register custom scripts or > > commands in the usual Tcl event handler style as error handlers. >=20 > Does "event" here have anything to do with the event loop=3F No, it has not. It's just the same "format" like commands for fileevent, w= indow event and so on. >=20 > > SPECIFICATION > > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > [...] >=20 > IMHO, this is not a specification, but rather a ChangeLog. I know.. sorry, I did'nt TIP before ;-). Its updated and hopefully better = now. > Attempting to recreate a functionality description from the information=20 > given, it seems like these error handlers would be called immediately=20 > when the error is thrown, just like e.g. a variable trace is called=20 > immediately when that variable is accessed. In view of that, it might=20 > perhaps be more appropriate to fully integrate this into the [trace]=20 > command (especially since this would provide established mechanisms for=20 > introspection and handler deletion). I thought about a [trace set errorcmd] or [trace add errorcmd]. Probably y= ou're right regarding the interface to this from a Tcl'ers point of view.=20 But the internal execution mechanism is different... it's not a "normal" t= race, which runs when all the other traces are executed, but only when the= re was an error. In fact, it is called after the command execution, if nec= essary as determined by the catch level and -caught/-uncaught flags. > Come to think of it, how much of this isn't already made possible by=20 > [trace add execution]=3F If you do [trace add execution main leavestep=20 > handler], where [main] is the main procedure of your program and=20 > [handler] is your designated error handler, then this handler will=20 > indeed be called whenever a command completes, and thus be given a=20 > chance to do something for those returns that have an error return=20 > code.=20 I made a section in the TIP explaining my experiences with that. Indeed I = thought it could be solved this way, but it was somewhat tedious in practi= ce... > (Even counting [catch]es could be handled using execution traces,=20 > if one trusts the user not to rename the [catch] command.) Speed is of=20 > course an issue, but if that is the main reason for this feature then=20 > the TIP should say so. As for the [catch]'es - I don't know how to capture them in a leavestep tr= ace. Its not obvious or easy, if possible at all. The speed issue is inclu= ded in the TIP now. >=20 > The distinction between caught and uncaught errors also seem a bit=20 > hazy. Many errors are caught (by control structures and the like) just=20 > to be rethrown, but it seems as the mechanism proposed here would=20 > simply consider them to be caught.=20 No, if they are rethrown, a new error is generated which is not considered= to be caught (if not caught elsewhere above, of course). > That is probably not what a user=20 > would expect, and a control structure implementor would want a=20 > mechanism for saying "this [catch] is not to count as catching errors". The custom command can be run on either caught errors or uncaught errors, = or both (depending on the -caught/-uncaught flags given to the registratio= n command). Everything else is up to the implementor of the registered com= mand (checking ::errorCode and ::errorInfo etc.). I think that is appropri= ate... Eckhard =5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F Viren-Scan f=FCr Ihren PC! Jetzt f=FCr jeden. Sofort, online und kostenlos. Gleich testen! http://www.pc-sicherheit.web.de/freescan/=3Fmc=3D022222 |
From: <ec...@we...> - 2006-11-03 08:17:52
|
> Yes, but the rethrowing of an error could take place very far from > where it originally happened. With something like > http://wiki.tcl.tk/using, you don't get the requested chance to debug > errors that happen within the [using], since that command catches and > rethrows errors. Just an endorsement to this... You wouldn't implement a procedure this way in practice. Why? Because you can't debug it with *any* method - it is useless here to catch the error just to rethrow it at a different place. The only good reason to catch an error and rethrow it is to do some special processing *immediately* - e.g. - close resources - do some logging mumble. - etc... In the case of [using], it would look like this: proc using {varName chan script} { upvar 1 $varName var set var $chan set rc [catch { uplevel 1 $script } result] # log any error and proceed if {$rc} { puts "Yipieee, an error: $result" } catch { close $chan } return -code $rc } or like this: proc using {varName chan script} { upvar 1 $varName var set var $chan set rc [catch { uplevel 1 $script } result] # step out on error. Close the channel before if {$rc} { catch {close $chan} error "Yippieee, there was an error: $result" } catch { close $chan } return $result } In the first case, you don't want to debug anything yet - you consider that it is enough to have it logged. In the second case, you get an error immediately, which can be trapped and debugged. BTW, the new [info frame] command (TIP #280) is very helpful here. Eckhard PS: <cite src="http://lambda-the-ultimate.org/node/1544#comment-18176"> People have an unfortunate tendency to ignore these basic conveniences and focus on hypothetical software-engineering mumbo-jumbo scenarios. "Oh my, what if Luke installed an exception handler that ROT13 encoded every string on the heap, then how would Jane debug her programs?" This is not the way to illumination. </cite> _____________________________________________________________________ Der WEB.DE SmartSurfer hilft bis zu 70% Ihrer Onlinekosten zu sparen! http://smartsurfer.web.de/?mc=100071&distributionid=000000000066 |
From: Eckhard L. <ec...@we...> - 2006-11-03 08:44:31
|
> Just an endorsement to this... You wouldn't implement a procedure this w= ay in practice. ^^^^ > Why=3F Because you can't debug it with *any* method - it is useless here t= o catch the error just to rethrow it at a different place. The only good r= eason to catch an error and rethrow it is to do some special processing *i= mmediately* - e.g. Ahhmm I should have seen that [using] actually *does* this kind of special= processing (by closing the $chan no matter if error or not). My fault, th= e above marked was a wrong statement... sorry. But the point stays the same. Eckhard =5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F Viren-Scan f=FCr Ihren PC! Jetzt f=FCr jeden. Sofort, online und kostenlos. Gleich testen! http://www.pc-sicherheit.web.de/freescan/=3Fmc=3D022222 |
From: Neil M. <ne...@cs...> - 2006-11-03 11:57:55
|
On 3 Nov 2006, at 08:44, Eckhard Lehmann wrote: >> Just an endorsement to this... You wouldn't implement a procedure >> this way in practice. > ^^^^ > >> Why? Because you can't debug it with *any* method - it is useless >> here to catch the error just to rethrow it at a different place. >> The only good reason to catch an error and rethrow it is to do >> some special processing *immediately* - e.g. > > Ahhmm I should have seen that [using] actually *does* this kind of > special processing (by closing the $chan no matter if error or > not). My fault, the above marked was a wrong statement... sorry. > > But the point stays the same. Actually, as the author of [using] and several other control constructs, I can say that you definitely do end up catching everything just to rethrow errors again. Apart from being essential in order to clean up resources (i.e., equivalent of a "finally" clause), it is also necessary if you want to catch "break" or "continue" exceptions. This isn't some obscure corner case: any time you want to [catch] anything you have to catch everything and then rethrow those exceptions you don't know how to deal with. -- Neil |
From: <ec...@we...> - 2006-11-03 12:46:41
|
> Actually, as the author of [using] and several other control > constructs, I can say that you definitely do end up catching > everything just to rethrow errors again. Apart from being essential > in order to clean up resources (i.e., equivalent of a "finally" > clause), it is also necessary if you want to catch "break" or > "continue" exceptions. This isn't some obscure corner case: any time > you want to [catch] anything you have to catch everything and then > rethrow those exceptions you don't know how to deal with. You mean things like this?: set err [catch {...} m] switch -- $err { 1 {do this} 2 {do that} default {return -code $err "Hae? $m"} } It means that you expect return codes 1 and 2, but everything else is not expected and thus rethrown. An errorhandler on -uncaught woud pitch in for the "default" branch above. It helps you not to find out where and how the error exactly happened in the catch {} block, although it helps you certainly to see how it came there. This makes me think whether it might be useful to register custom handlers for different return codes... Eckhard _____________________________________________________________________ Der WEB.DE SmartSurfer hilft bis zu 70% Ihrer Onlinekosten zu sparen! http://smartsurfer.web.de/?mc=100071&distributionid=000000000066 |
From: <Lar...@re...> - 2006-11-02 16:18:47
|
2006-11-02 kl. 14.34 skrev Eckhard Lehmann: > >> >>> SPECIFICATION >>> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >> [...] >> >> IMHO, this is not a specification, but rather a ChangeLog. > > I know.. sorry, I did'nt TIP before ;-). Its updated and hopefully=20 > better now. It still doesn't describe the ::tcl::seterrorhandler command very much=20= (syntax, return value, etc.). Nor is there much said about the handler=20= command itself (With which arguments is it called? Is there any way in=20= which it can quell the error?) One would also want the bulleted list after "The changes in the=20 execution engine should be done so that:" to be followed by an=20 explanation of how you mean to meet these conditions. For example, it=20 is stated that the ::errorInfo and ::errorCode variables are updated.=20 Does this mean that e.g. any write traces on these variables would fire=20= differently with the TIP mechanisms in place than without them? Is there meant to be any interaction with the event loop? Having a=20 Tk-based debugger probably means running the event loop (probably via=20 [vwait]), and as far as I can tell this error handling mechanism is=20 then turned off. However, the rest of the application (channel events,=20= GUI events, [after] scripts) would continue to run, and do so without=20 the "protection" of an error handler. This could be considered=20 undesirable. >> Attempting to recreate a functionality description from the=20 >> information >> given, it seems like these error handlers would be called immediately >> when the error is thrown, just like e.g. a variable trace is called >> immediately when that variable is accessed. In view of that, it might >> perhaps be more appropriate to fully integrate this into the [trace] >> command (especially since this would provide established mechanisms=20= >> for >> introspection and handler deletion). > > I thought about a [trace set errorcmd] or [trace add errorcmd]. I'd go for [trace add error]. > Probably you're right regarding the interface to this from a Tcl'ers=20= > point of view. But the internal execution mechanism is different... More different than an execution trace is from a variable trace? >> (Even counting [catch]es could be handled using execution traces, >> if one trusts the user not to rename the [catch] command.) Speed is = of >> course an issue, but if that is the main reason for this feature then >> the TIP should say so. > > As for the [catch]'es - I don't know how to capture them in a=20 > leavestep trace. No, a *leavestep* trace could be a bit roundabout. I'd do that bit by=20 putting *enter* and *leave* traces on [catch] that increment/decrement=20= a variable. > Its not obvious or easy, if possible at all. The speed issue is=20 > included in the TIP now. > >> >> The distinction between caught and uncaught errors also seem a bit >> hazy. Many errors are caught (by control structures and the like) = just >> to be rethrown, but it seems as the mechanism proposed here would >> simply consider them to be caught. > > No, if they are rethrown, a new error is generated which is not=20 > considered to be caught (if not caught elsewhere above, of course). Yes, but the rethrowing of an error could take place very far from=20 where it originally happened. With something like=20 http://wiki.tcl.tk/using, you don't get the requested chance to debug=20 errors that happen within the [using], since that command catches and=20 rethrows errors. Lars Hellstr=F6m= |
From: Eckhard L. <ec...@we...> - 2006-11-02 19:42:41
|
Lars Hellstr=F6m schrieb: > It still doesn't describe the ::tcl::seterrorhandler command very much=20 > (syntax, return value, etc.). Nor is there much said about the handler=20 > command itself (With which arguments is it called? Is there any way in=20 > which it can quell the error?) > > One would also want the bulleted list after "The changes in the=20 > execution engine should be done so that:" to be followed by an=20 > explanation of how you mean to meet these conditions. For example, it=20 > is stated that the ::errorInfo and ::errorCode variables are updated.=20 > Does this mean that e.g. any write traces on these variables would=20 > fire differently with the TIP mechanisms in place than without them? I updated the specification again. Hope that these questions are=20 answered now... > Is there meant to be any interaction with the event loop? Having a=20 > Tk-based debugger probably means running the event loop (probably via=20 > [vwait]), and as far as I can tell this error handling mechanism is=20 > then turned off. However, the rest of the application (channel events,=20 > GUI events, [after] scripts) would continue to run, and do so without=20 > the "protection" of an error handler. This could be considered=20 > undesirable. Good point... I didn't consider the event loop so far. It would mean to be able to trigger the error handler again in event=20 loop scripts (e.g. in "after" code) , if it runs already at the same=20 time. Currently it can be only run once at a time - if errors in the=20 same Interp are thrown during the handler runs, they are handled as=20 usual. This is however different from the behaviour in different threads=20 since there are other Interp's. >> I thought about a [trace set errorcmd] or [trace add errorcmd]. > > I'd go for [trace add error]. I'd rather go for [trace set error], because it's only one command. [trace add error] could mean that the script is run in addition to the=20 usual implementation (which is not the case) or that there can be more=20 scripts registered. Technically, this wouldn't be a problem, but it makes things more=20 complicated than necessary. In general, one custom handler is enough -=20 it's again up to the implementor of this handler to call other procedures= . >> Probably you're right regarding the interface to this from a Tcl'ers=20 >> point of view. But the internal execution mechanism is different... > > More different than an execution trace is from a variable trace? The error handler is to be run whenever the return code of the current=20 command is TCL_ERROR. I think that is maybe simpler than the "execution=20 trace" mechanism... >> No, if they are rethrown, a new error is generated which is not=20 >> considered to be caught (if not caught elsewhere above, of course). > > Yes, but the rethrowing of an error could take place very far from=20 > where it originally happened.=20 It doesn't matter where it is thrown or rethrown. As soon as it appears,=20 it is trapped (provided, the -uncaught flag is set). That's the whole=20 point of this TIP. > With something like http://wiki.tcl.tk/using, you don't get the=20 > requested chance to debug errors that happen within the [using], since=20 > that command catches and rethrows errors. That's a rather special case. Set the -caught flag to trap caught=20 errors. This can be done dynamically during program run from somewhere... Eckhard |