Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

trapping errors inside an event loop

34 views
Skip to first unread message

Mark Tarver

unread,
Jan 27, 2024, 6:56:14 AMJan 27
to
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.

Mark

Rich

unread,
Jan 27, 2024, 11:08:53 AMJan 27
to
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.

Gerald Lester

unread,
Jan 27, 2024, 11:45:41 AMJan 27
to
Actually, you don't want [eval $Command] -- you just want $Command


Christian Gollwitzer

unread,
Jan 27, 2024, 12:13:12 PMJan 27
to
Am 27.01.24 um 17:45 schrieb Gerald Lester:
> On 1/27/24 10:08, Rich wrote:
>> Mark Tarver <dr.mt...@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

Mark Tarver

unread,
Jan 30, 2024, 6:06:50 AMJan 30
to
That's great; the program is working now. Thanks to all.

Mark
0 new messages