Tcl code within or called from a PL/Tcl function can raise an
error, either by executing some invalid operation or by generating
an error using the Tcl error
command
or PL/Tcl's elog
command. Such errors
can be caught within Tcl using the Tcl catch
command. If an error is not caught but is
allowed to propagate out to the top level of execution of the
PL/Tcl function, it is reported as a SQL error in the function's
calling query.
Conversely, SQL errors that occur within PL/Tcl's spi_exec
, spi_prepare
, and spi_execp
commands are reported as Tcl errors, so
they are catchable by Tcl's catch
command. (Each of these PL/Tcl commands runs its SQL operation in a
subtransaction, which is rolled back on error, so that any
partially-completed operation is automatically cleaned up.) Again,
if an error propagates out to the top level without being caught,
it turns back into a SQL error.
Tcl provides an errorCode
variable
that can represent additional information about an error in a form
that is easy for Tcl programs to interpret. The contents are in Tcl
list format, and the first word identifies the subsystem or library
reporting the error; beyond that the contents are left to the
individual subsystem or library. For database errors reported by
PL/Tcl commands, the first word is POSTGRES
, the second word is the PostgreSQL
version number, and additional words are field name/value pairs
providing detailed information about the error. Fields SQLSTATE
, condition
,
and message
are always supplied (the
first two represent the error code and condition name as shown in
Appendix A).
Fields that may be present include detail
, hint
,
context
, schema
, table
,
column
, datatype
, constraint
,
statement
, cursor_position
, filename
, lineno
, and
funcname
.
A convenient way to work with PL/Tcl's errorCode
information is to load it into an array,
so that the field names become array subscripts. Code for doing
that might look like
if {[catch { spi_exec $sql_command }]} { if {[lindex $::errorCode 0] == "POSTGRES"} { array set errorArray $::errorCode if {$errorArray(condition) == "undefined_table"} { # deal with missing table } else { # deal with some other type of SQL error } } }
(The double colons explicitly specify that errorCode
is a global variable.)
If you see anything in the documentation that is not correct, does not match your experience with the particular feature or requires further clarification, please use this form to report a documentation issue.