From: Don Porter on
Don Porter wrote:
> cattaghia wrote:
>> Yeah I agree, Don, but, like I said, this would be useful in a
>> scenario where really unexpected errors could happen. For example,
>> when your application sources a script which was not written by
>> yourself, and you can not assure that it uses "catch" appropriately
>> all the time, or any other buggy thing (and you�re not running the
>> script in another interp).

> So, is it [source] that is the bad actor?

I'd say no. It's the functioning of [source] and its C counterparts
Tcl_*EvalFile*() to pass back the return code to the caller so that
the script can [catch] or the C code can do its own check for TCL_OK
as it sees fit.

Larry Virden is right. We need less design philosophy and more
concrete examples of what troubles you are having.

--
| Don Porter Mathematical and Computational Sciences Division |
| donald.porter(a)nist.gov Information Technology Laboratory |
| http://math.nist.gov/~DPorter/ NIST |
|______________________________________________________________________|
From: cattaghia on
Hi all, thanks once again! It's becoming an interesting lesson on Tcl
internals!

It is not exactly that I'm running into troubles with this; it would
be only one more security resource for avoiding an application to
break due to a coding mishappening. Suppose the following procedure is
sourced into, let's say, Tkcon:

package require Tk
proc ohno {errorstring returnopts} {
tk_messageBox -icon error -message $errorstring
return 1
}

As ridiculous as it is, this proc will be our error treatment routine.
If we want it to handle a background error, we can do that using the
console in Tkcon itself...

% interp bgerror {} ohno

.... and from now on we can create a button with its -command option
designed to something like {expr 2/0}. When the button is clicked, an
error will happen and ohno will be called, right? We can also do
something like that:

% rename unknown -unknown
% proc unknown {args} { return [ohno "Whatcha mean?" $args] }

.... and we will also have the ohno proc being called when we type in
the console a command like "dothat".

However, if we type in the console something like ...

% expr {2/0}

.... we will get an error, the type I have mentioned as a "common
error". The error message will be shown in the console and further
evaluation is aborted. Of course this example is too simple and it
shows a predictable (or better, an obvious) error, but it is possible
to any of us that we create a Tk application which runs user-made or
third-party scripts and in one of these scripts there is an uncatched
error that will cause the same crash.

Surely there are alternatives like running the buggy script under a
safe interpreter, but what I was looking for was a way to define a
procedure which would handle those errors as last resource, instead of
just letting the script evaluation abort and pop an error message in
the console. Imagine that Tcl supported a special proc name
"::errormgr" which could be used like the traditional bgerror. If I
did something like this in the console...

% proc errormgr {errorstring returnoptions} { return [ohno
$errorstring $returnoptions] }

.... then typed ...

% expr 2/0

.... the ::errormgr special procedure would be called, and it would
call ohno, which would show a nifty dialog box containing the error
message (or do something more useful). If no procedure was defined
under the ::errormgr name, the interpreter would do what it usually
does -- i.e., show the error message in the console and abort the
script.

I just hope I've made it clear now! Thanks!

Fabricio Rocha
From: Don Porter on
cattaghia wrote:
> I just hope I've made it clear now! Thanks!

No. Not really. You went on at great (!) length talking about
analogies with background error handling and unknown command
dispatch. When you finally got to the point, the only example
offered is one you yourself says is "too simple" to actually make your
point.

> However, if we type in the console something like ...
>
> % expr {2/0}
>
> ... we will get an error, the type I have mentioned as a "common
> error". The error message will be shown in the console and further
> evaluation is aborted. Of course this example is too simple and it
> shows a predictable (or better, an obvious) error, but it is possible
> to any of us that we create a Tk application which runs user-made or
> third-party scripts and in one of these scripts there is an uncatched
> error that will cause the same crash.

Then you launch into speculation about possible solutions, but I'm still
back at the train station waiting for a clear-headed description of
just what the problem is. Please focus on that.

Your example above is mistaken in important ways. Since you're
showing an interactive prompt, I'm assuming you're talking about the
interactive evaluation loop built into Tcl_Main(). There is no "crash"
in your example at all. The Tcl_RecordAndEvalObj() call inside Tcl_Main
which does the evaluation of commands typed interactively does check
its return code, and when TCL_ERROR is returned, the error message is
reported by writing it to the stderr channel, and then interactive
command prompting continues. No crash at all. Exactly the [catch] and
report function that ought to be in place to prevent an actual crash yet
react in some useful way to the error reported by evaluation.

Maybe you are just looking for some way to customize the particular
reporting choice used by Tcl_Main() ? I got the sense you were looking
for something more general, but still not clear why, or whether that
desire is simply mistaken.

To explain a bit why my demands for clarity may be stronger than you
expected, your subject line asks for callbacks when we "reach the
global scope". There are several related but distinct concepts that
might match that. "Global scope" might mean the global namespace.
It might mean the top frame level such as can be accessed via
[uplevel #0]. Or it might mean the internal condition that
iPtr->numLevels == 0 . I don't think a hook on any of these things
is the right idea, but without better examples of actual problems
I can't even narrow down the possibilities.

Since you mentioned untrusted scripts ("user-made or third-party") I
do offer the conventional advice that

catch {$slave eval $script} m o

is the way to handle them, with $slave suitably handicapped so that
script cannot do anything destructive, and with post-processing of
the return code, result, and options dictionary as suitable.

--
| Don Porter Mathematical and Computational Sciences Division |
| donald.porter(a)nist.gov Information Technology Laboratory |
| http://math.nist.gov/~DPorter/ NIST |
|______________________________________________________________________|
From: Ralf Fassel on
* cattaghia <cattaghia(a)ig.com.br>
| it would be only one more security resource for avoiding an
| application to break due to a coding mishappening.

If you talk about bgerror: the application still runs ok if bgerror is
invoked. The event loop is running, events are served etc. I don't see
any problem here.

If you talk about 'error' not aborting a script: don't do that.
I certainly have coded lots of my apps with the expectation:

if {some_invalid_condition} {
error "some_invalid_condition happened"
# this line not reached if the error triggered
puts "How did we get *here*?"
}

If this script continues after the 'error' because of some top-level
substitution command returns an OK instead of aborting the script,
at least 'undefined behaviour'.

R'
From: cattaghia on
Thanks, Don and Ralf!

I think you actually got the point with this, Don:

"Maybe you are just looking for some way to customize the particular
reporting choice used by Tcl_Main() ?"

Exactly that. It seemed to me a feasible thing, because that's what
the interpreter seems to do when it finds a call to a non-existant
command (by running a Tcl procedure called unknown, or one defined by
namespace unknown) or when an error happens in a delayed evaluation of
a script which depends on an event (the bgerror scheme). And thanks by
providing the correct words for what I meant -- "top frame level such
as can be accessed via [uplevel #0]" (I think I'll never get used with
all the meanings of the word "frame").

I imagine this could allow a simple way to redirect the error
reporting to a procedure which would show the error message in a Tk
dialog, or add it to an error log file, or try a "last rite" attempt
to salvage the user's data before a crash (in the application; I did
not mean crash on the Tcl interpreter itself), or show an input dialog
in which the user could type a value that the faulty procedure was
supposed to return (this would be useful during development, when we
often use stubs and write procedures which use another procedures that
we still haven't written and tested properly).

And I agree, Ralf, that continuing after an error can be dangerous;
but then this risk would be assumed by the application and its
developer.

Thanks!

Fabricio