42.8. Manejo de errores en PL/Tcl #

El código Tcl dentro de una función PL/Tcl (o llamado por esta) puede generar un error, ya sea ejecutando alguna operación no válida o generando un error mediante el comando error de Tcl o el comando elog de PL/Tcl. Tales errores se pueden capturar dentro de Tcl usando el comando catch de Tcl. Si un error no se captura, sino que se propaga hasta el nivel superior de ejecución de la función PL/Tcl, se reportará como un error SQL en la consulta que llama a la función.

Por el contrario, los errores SQL que ocurren dentro de los comandos spi_exec, spi_prepare y spi_execp de PL/Tcl se reportan como errores de Tcl, por lo que son capturables mediante el comando catch de Tcl. (Cada uno de estos comandos de PL/Tcl ejecuta su operación SQL en una subtransacción, la cual se revierte en caso de error, de modo que cualquier operación parcialmente completada se limpia automáticamente). De nuevo, si un error se propaga hasta el nivel superior sin ser capturado, se convierte de nuevo en un error SQL.

Tcl proporciona una variable errorCode que puede representar información adicional sobre un error de una forma que resulta fácil de interpretar para los programas Tcl. El contenido está en el formato de lista de Tcl, y la primera palabra identifica el subsistema o biblioteca que reporta el error; más allá de eso, el contenido se deja al criterio del subsistema o biblioteca individual. Para los errores de base de datos reportados por los comandos de PL/Tcl, la primera palabra es POSTGRES, la segunda palabra es el número de versión de PostgreSQL, y las palabras adicionales son pares de nombre/valor de campo que proporcionan información detallada sobre el error. Siempre se suministran los campos SQLSTATE, condition y message (los dos primeros representan el código de error y el nombre de la condición como se muestra en el Appendix A). Los campos que pueden estar presentes incluyen detail, hint, context, schema, table, column, datatype, constraint, statement, cursor_position, filename, lineno y funcname.

Una forma conveniente de trabajar con la información de errorCode de PL/Tcl es cargarla en un arreglo (array), de modo que los nombres de los campos se conviertan en índices del arreglo. El código para hacer esto podría verse así:

if {[catch { spi_exec $sql_command }]} {
    if {[lindex $::errorCode 0] == "POSTGRES"} {
        array set errorArray $::errorCode
        if {$errorArray(condition) == "undefined_table"} {
            # manejar tabla no definida
        } else {
            # manejar algún otro tipo de error SQL
        }
    }
}

(Los dos puntos dobles especifican explícitamente que errorCode es una variable global).