• Re: trapping errors inside an event loop

    From Rich@21:1/5 to Mark Tarver on Sat Jan 27 16:08:48 2024
    Mark Tarver <dr.mtarver@gmail.com> wrote:
    I'm trying to trap errors inside an event loop. Here is the relevant code

    proc enact {File} {
    set Source [open $File r]
    set Data [read $Source]
    set Command [trim $Data]
    overwrite $File
    catch [eval $Command] err
    if { $err != 0 } {
    send [concat "(error " $err ")"] }
    close $Source}

    To test this I sent the invalid command 'what .b' rather than say
    'button .b'.

    I expected TCL/tk to send an error message using 'send' and continue
    the loop. However what happens is that the loop exits with an error
    message 'invalid command what' and on examination I found the message
    has been sent using 'send'. So in some sense it was caught and yet
    it was not caught because the loop exited. Puzzling.

    You are testing the error "message" against zero, but you get an
    indication of error from catch from the return code of catch itself.

    You want to do this:

    if {[catch [eval $Command] result] != 0} {
    ...

    or

    set r [catch [eval $Command] result]
    if {$r != 0} {
    ...


    As it stands (i.e., as you've shown us the code) there is no event loop running, so enact will run once each time it is called. And nothing
    shows how it is being called.

    You also omitted the 'app' name above from the send. You have the
    "cmd" and "args" but no "app". So your [send] call is incorrect above.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Christian Gollwitzer@21:1/5 to All on Sat Jan 27 18:13:07 2024
    Am 27.01.24 um 17:45 schrieb Gerald Lester:
    On 1/27/24 10:08, Rich wrote:
    Mark Tarver <dr.mtarver@gmail.com> wrote:
    I'm trying to trap errors inside an event loop.  Here is the relevant
    code

    proc enact {File} {
       set Source [open $File r]
       set Data [read $Source]
       set Command [trim $Data]
       overwrite $File
       catch [eval $Command] err
       if { $err != 0 } {
            ...
    Actually, you don't want [eval $Command] -- you just want $Command

    To put it together: The correct invocation would be:

    if {[catch $Command result]} {
    # an error has happened
    # the error message is in $result
    } else {
    # it went smoothly
    # the reult of $Command is in $result
    }

    Catch executes the 1st arg, i.e.

    catch $Command result

    is the same as

    set result [eval $Command]

    - with the difference that it catches the errors.

    Also note that the command is executed in the current scope. I.e. if
    Command is "set a 3", then the variable a inside the proc enact will be
    set. Most systems that execute such commands, e.g. Tk button commands
    etc., rather use the global level via

    catch {uplevel #0 $Command}

    Christian

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)