• Show argument values in bgerror

    From alexandru.dadalau@alexandru.dadalau@meshparts.de (alexandru) to comp.lang.tcl on Tue Sep 17 21:31:25 2024
    From Newsgroup: comp.lang.tcl

    I have this ::bgerror function to help debug errors in program flow:

    proc ::bgerror {message} {
    global errorInfo
    puts "*** START OF ERROR MESSAGE ***\n$message\n$errorInfo\n*** END OF
    ERROR MESSAGE ***"
    }

    The issue is, that the errorInfo does not show the values of the
    arguments of called procedures in the stack.
    Thus it's often not clear which arguments lead the the error.
    Is there a trick how to show the values with which the procedures were
    called in the stack prior to the error?

    Many thanks
    Alexandru
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From et99@et99@rocketship1.me to comp.lang.tcl on Tue Sep 17 19:32:55 2024
    From Newsgroup: comp.lang.tcl

    On 9/17/2024 2:31 PM, alexandru wrote:
    I have this ::bgerror function to help debug errors in program flow:

    proc ::bgerror {message} {
     global errorInfo
     puts "*** START OF ERROR MESSAGE ***\n$message\n$errorInfo\n*** END OF ERROR MESSAGE ***"
    }

    The issue is, that the errorInfo does not show the values of the
    arguments of called procedures in the stack.
    Thus it's often not clear which arguments lead the the error.
    Is there a trick how to show the values with which the procedures were
    called in the stack prior to the error?

    Many thanks
    Alexandru


    Here's some test code I cobbled together, I think there may be something here that does what you want. The "info level [info level]" might be just what you need, if issued at the proper uplevel. Note, the outer info has 2 args, the inner info only 1 and that's intentional. You likely would iterate on uplevel's and toss ones that give an error.

    console show
    proc foo {} {foo2 11 22 33}

    proc foo2 {a b c} {set x 1; set y 2; foo3}

    proc foo3 {} {
    set level [info frame]
    puts "level= |$level| "
    set vars [ \
    uplevel 1 {
    set _vars [info vars]
    puts "_vars= |$_vars| level= [info frame] args= [info level [info level]]"
    foreach _var $_vars {
    puts " _var= |$_var| "
    lappend _varsx "$_var = [set $_var]"
    }
    set _varsx
    }
    ]
    puts "vars= |$vars| "
    puts [join $vars \n]
    }
    if [catch {
    foo
    } err_code] {
    puts $err_code
    }

    output:

    level= |9|
    _vars= |a b c x y| level= 10 args= foo2 11 22 33
    _var= |a|
    _var= |b|
    _var= |c|
    _var= |x|
    _var= |y|
    vars= |{a = 11} {b = 22} {c = 33} {x = 1} {y = 2}|
    a = 11
    b = 22
    c = 33
    x = 1
    y = 2

    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Harald Oehlmann@wortkarg3@yahoo.com to comp.lang.tcl on Wed Sep 18 09:14:34 2024
    From Newsgroup: comp.lang.tcl

    Am 17.09.2024 um 23:31 schrieb alexandru:
    I have this ::bgerror function to help debug errors in program flow:

    proc ::bgerror {message} {
     global errorInfo
     puts "*** START OF ERROR MESSAGE ***\n$message\n$errorInfo\n*** END OF ERROR MESSAGE ***"
    }

    The issue is, that the errorInfo does not show the values of the
    arguments of called procedures in the stack.
    Thus it's often not clear which arguments lead the the error.
    Is there a trick how to show the values with which the procedures were
    called in the stack prior to the error?

    Many thanks
    Alexandru

    info errorstack ?

    % proc e {v} {incr v}
    % e a
    expected integer but got "a"
    % set errorInfo
    expected integer but got "a"
    while executing
    "incr v"
    (procedure "e" line 1)
    invoked from within
    "e a"
    % info errorstack
    INNER incrScalar1Imm CALL {e a}

    Harald
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From alexandru.dadalau@alexandru.dadalau@meshparts.de (alexandru) to comp.lang.tcl on Wed Sep 18 10:24:23 2024
    From Newsgroup: comp.lang.tcl

    Wow, thanks for the input. I'll try to use it to solve the problem.

    Regards
    Alexandru
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From alexandru.dadalau@alexandru.dadalau@meshparts.de (alexandru) to comp.lang.tcl on Wed Sep 18 10:23:34 2024
    From Newsgroup: comp.lang.tcl

    Hi Harald,

    I'll use your example with small changes to explain the issue:

    proc e {v} {incr v}
    set x "a"
    e $x
    puts $errorInfo

    will output:

    expected integer but got "a"
    while executing
    "incr v"
    (procedure "e" line 1)
    invoked from within
    "e $x"
    (file "C:/arbeit/MESHPARTS-Software/test3.tcl" line 4)
    invoked from within
    "source -encoding utf-8 C:/arbeit/MESHPARTS-Software/test3.tcl"

    As you can see, upstream procedure calls are printed with dollar sign, unevaluated values.
    In more complex nested calls, the information about arguments gets lost
    and errorInfo does not show which argument values were used.
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Harald Oehlmann@wortkarg3@yahoo.com to comp.lang.tcl on Wed Sep 18 13:50:21 2024
    From Newsgroup: comp.lang.tcl

    Am 18.09.2024 um 12:23 schrieb alexandru:
    As you can see, upstream procedure calls are printed with dollar sign, unevaluated values.
    In more complex nested calls, the information about arguments gets lost
    and errorInfo does not show which argument values were used.

    That is exactly what "info errorstack" is about.
    See, that the "a" is substituted as argument "v".
    It only works for items putting something on the call stack, so, it will
    not help for your eval example. But you get the values supplied to all procedures...

    Take care,
    Harald

    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From alexandru.dadalau@alexandru.dadalau@meshparts.de (alexandru) to comp.lang.tcl on Wed Sep 18 13:21:12 2024
    From Newsgroup: comp.lang.tcl

    Here is the errorInfo of a true life situation.
    The value of "val" is not output.
    Maybe it should and it was intended so, but it's not.
    So it's a bug then...

    *** ERROR ***
    Time: Monday, das 16 von September, 2024, um 13:24:37
    integer value too large to represent
    while executing
    "expr {round($val*(10.0**($decimals+3)))/(10.0**$decimals)}"
    (procedure "NumberReadmm" line 5)
    invoked from within
    "NumberReadmm $contact_offset 6"
    (procedure "ContactOffsetFormat" line 7)
    invoked from within
    "ContactOffsetFormat $contact_offset_min"
    (procedure "UIRelationApplyContactOffset" line 45)
    invoked from within
    "UIRelationApplyContactOffset %W"
    invoked from within
    ".valid.notebook.f5.buttons.b2 invoke "
    invoked from within
    ".valid.notebook.f5.buttons.b2 instate !disabled {
    valid.notebook.f5.buttons.b2 invoke } "
    invoked from within
    ".valid.notebook.f5.buttons.b2 instate pressed {
    valid.notebook.f5.buttons.b2 state !pressed;
    valid.notebook.f5.buttons.b2 instate !disabled { .valid..."
    (command bound to event)
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Don Porter@donald.porter@nist.gov to comp.lang.tcl on Wed Sep 18 09:46:54 2024
    From Newsgroup: comp.lang.tcl


    The [interp bgerror] command has been available since the release
    of Tcl 8.5.0 in 2007. No one should be continuing to struggle against
    the deficits of the [bgerror] facility.

    On 9/17/24 17:31, alexandru wrote:
    I have this ::bgerror function to help debug errors in program flow:

    proc ::bgerror {message} {
     global errorInfo
     puts "*** START OF ERROR MESSAGE ***\n$message\n$errorInfo\n*** END OF ERROR MESSAGE ***"
    }

    The issue is, that the errorInfo does not show the values of the
    arguments of called procedures in the stack.
    Thus it's often not clear which arguments lead the the error.
    Is there a trick how to show the values with which the procedures were
    called in the stack prior to the error?

    Many thanks
    Alexandru
    --
    | Don Porter Applied and Computational Mathematics Division |
    | donald.porter@nist.gov Information Technology Laboratory |
    | http://math.nist.gov/~DPorter/ NIST | |______________________________________________________________________|

    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Harald Oehlmann@wortkarg3@yahoo.com to comp.lang.tcl on Wed Sep 18 16:54:35 2024
    From Newsgroup: comp.lang.tcl

    Am 18.09.2024 um 15:21 schrieb alexandru:
    Here is the errorInfo of a true life situation.
    The value of "val" is not output.
    Maybe it should and it was intended so, but it's not.
    So it's a bug then...

    Alexandru,
    it is not a bug. I don't speak about $::errorInfo, but "info
    errorstack", or the "-errorstack" component of the error dict.

    Here is a complete example as proposed by Don (thanks !):

    proc bgerrorhandler {message errordict} {
    puts "*** START OF ERROR MESSAGE ***"
    puts $message
    puts "*** ERROR INFO ***"
    puts [dict get $errordict -errorinfo]
    puts "*** ERROR STACK ***"
    foreach {call arg} [dict get $errordict -errorstack] {
    puts "$call:$arg"
    }
    puts "*** END OF ERROR MESSAGE ***"
    }
    interp bgerror "" bgerrorhandler
    proc e1 {v} {incr v}
    proc e2 {v} {e1 $v}
    after idle {e2 a}

    This gives the output:
    *** START OF ERROR MESSAGE ***
    expected integer but got "a"
    *** ERROR INFO ***
    expected integer but got "a"
    while executing
    "incr v"
    (procedure "e1" line 1)
    invoked from within
    "e1 $v"
    (procedure "e2" line 1)
    invoked from within
    "e2 a"
    ("after" script)
    *** ERROR STACK ***
    INNER:incrScalar1Imm
    CALL:e1 a
    CALL:e2 a
    *** END OF ERROR MESSAGE ***

    So, the error info has the variable names ($v in this case), while the
    error stack has the values ("a" in this case).

    Might this suit your needs ?

    Take care,
    Harald

    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From alexandru.dadalau@alexandru.dadalau@meshparts.de (alexandru) to comp.lang.tcl on Fri Sep 20 12:04:38 2024
    From Newsgroup: comp.lang.tcl

    Thanks Harald,

    This code perfectly solves my problem.

    Best regards
    Alexandru
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From r.zaumseil@r.zaumseil@freenet.de (rene) to comp.lang.tcl on Tue Sep 24 05:54:14 2024
    From Newsgroup: comp.lang.tcl

    Hello Harald,

    where did you find the second "errordict" argument of the new bgerror
    proc. In the bgerror documentation is only the "message" argument.
    May be a documentation error?

    Regards
    Rene

    PS. I will try to answer the oo question later this week.
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Harald Oehlmann@wortkarg3@yahoo.com to comp.lang.tcl on Sun Oct 13 13:03:11 2024
    From Newsgroup: comp.lang.tcl

    Am 24.09.2024 um 07:54 schrieb rene:
    Hello Harald,

    where did you find the second "errordict" argument of the new bgerror
    proc. In the bgerror documentation is only the "message" argument.
    May be a documentation error?
    No, this is correct. The bgerror procedure is the old fashion and is
    obsolete. Use the interp bgerror described here: https://www.tcl-lang.org/man/tcl8.6/TclCmd/interp.htm#M55

    The two arguments are described in the subsection "Background error
    handling"

    PS. I will try to answer the oo question later this week.

    Great !

    Thank you,
    Harald
    --- Synchronet 3.20a-Linux NewsLink 1.114