2 42.8. Error Handling in PL/Tcl #
4 Tcl code within or called from a PL/Tcl function can raise an error,
5 either by executing some invalid operation or by generating an error
6 using the Tcl error command or PL/Tcl's elog command. Such errors can
7 be caught within Tcl using the Tcl catch command. If an error is not
8 caught but is allowed to propagate out to the top level of execution of
9 the PL/Tcl function, it is reported as an SQL error in the function's
12 Conversely, SQL errors that occur within PL/Tcl's spi_exec,
13 spi_prepare, and spi_execp commands are reported as Tcl errors, so they
14 are catchable by Tcl's catch command. (Each of these PL/Tcl commands
15 runs its SQL operation in a subtransaction, which is rolled back on
16 error, so that any partially-completed operation is automatically
17 cleaned up.) Again, if an error propagates out to the top level without
18 being caught, it turns back into an SQL error.
20 Tcl provides an errorCode variable that can represent additional
21 information about an error in a form that is easy for Tcl programs to
22 interpret. The contents are in Tcl list format, and the first word
23 identifies the subsystem or library reporting the error; beyond that
24 the contents are left to the individual subsystem or library. For
25 database errors reported by PL/Tcl commands, the first word is
26 POSTGRES, the second word is the PostgreSQL version number, and
27 additional words are field name/value pairs providing detailed
28 information about the error. Fields SQLSTATE, condition, and message
29 are always supplied (the first two represent the error code and
30 condition name as shown in Appendix A). Fields that may be present
31 include detail, hint, context, schema, table, column, datatype,
32 constraint, statement, cursor_position, filename, lineno, and funcname.
34 A convenient way to work with PL/Tcl's errorCode information is to load
35 it into an array, so that the field names become array subscripts. Code
36 for doing that might look like
37 if {[catch { spi_exec $sql_command }]} {
38 if {[lindex $::errorCode 0] == "POSTGRES"} {
39 array set errorArray $::errorCode
40 if {$errorArray(condition) == "undefined_table"} {
41 # deal with missing table
43 # deal with some other type of SQL error
48 (The double colons explicitly specify that errorCode is a global