Handling Tcl Errors - 2020.2 English

Vivado Design Suite User Guide: Using Tcl Scripting (UG894)

Document ID
UG894
Release Date
2021-03-30
Version
2020.2 English

Some built-in Tcl commands (but also user procs) can generate a Tcl error (TCL_ERROR) that can stop the execution of the script if the error is not caught by the program. An example is the file command that generates a TCL_ERROR when the file cannot be opened.

To do safe programming and catch the TCL_ERROR condition, Tcl has a built-in catch command that returns 1 when an error is caught and otherwise returns 0. The catch command can be used on a single command or a set of commands.

The basic syntax of the catch command is:

catch script [varname]

Where the script is a single or a set of Tcl commands and varname is a variable name in which the message explaining the TCL_ERROR is saved.

Note: The varname argument is optional.

The catch command is often used as illustrated below:

If {[catch script errorstring]} {
  # A low-level TCL_ERROR happened
  puts " Error - $errorstring "
} else {
  # No TCL_ERROR was generated
  puts " The code completed successfully "
}

Example 1 can be made safer using the catch command to cover the case where the file cannot be opened:

Example 3: Check when a file is opened for read/write (safe version).

if {[file exists $filename]} {
  if {[catch { set FH [open $filename r] } errorstring]} {
    puts " File $filename could not be opened : $errorstring"
  } else {
    # The file is opened, do something
    # …
    close $FH
  }
} else {
  puts " File $filename does not exist"
}

A Tcl error can also be user generated using the error command. This can be used, for example, to propagate a TCL_ERROR that is caught with the catch command to the upper level (bubbling). However, the error command can be used as well to generate a TCL_ERROR when, for example, a corner case is not supported by the script or an unexpected condition has happened in the code.

For example, the proc below returns the file content or generates a TCL_ERROR when the file cannot be opened:

proc get_file_content { filename } {
  if {[catch {
    set FH [open $filename r]
    set content [read $FH]
    close $FH
  } errorstring]} {
    error " File $filename could not be opened : $errorstring "
  }
  return $content
} 

The proc get_file_content can be called through a catch command to catch the potential error:

if {[catch { set content [get_file_content ./myreport.rpt] } errorstring]} {
  puts " The following error was generated: $errorstring "
} else {
  puts " The content of the file is: $content "
}

Example 2 can also be improved to generate a TCL_ERROR when a wrong condition occurs as shown in Example 4:

Example 4: Check that the Vivado objects are valid. Generate a TCL_ERROR otherwise (revised).

proc get_pin_dir { pinName } {
  if {$pinName == {}} {
    error " Error - no pin name provided"
  }
  set pin [get_pins $pinName]
  if {$pin == {}} {
    error " Error - pin $pinName does not exist"
  }
  set direction [get_property DIRECTION $pin]
  return $direction
}