55.2. Reportar errores dentro del servidor #

Los mensajes de error, advertencia y registro generados dentro del código del servidor deben crearse utilizando ereport, o su primo más antiguo elog. El uso de esta función es lo suficientemente complejo como para requerir alguna explicación.

Hay dos elementos obligatorios para cada mensaje: un nivel de severidad (que va desde DEBUG hasta PANIC, definidos en src/include/utils/elog.h) y un texto de mensaje principal. Además, hay elementos opcionales, el más común de los cuales es un código identificador de error que sigue las convenciones SQLSTATE de la especificación SQL. ereport en sí es solo una macro de envoltura (shell macro) que existe principalmente por la conveniencia sintáctica de hacer que la generación de mensajes parezca una sola llamada a función en el código fuente de C. El único parámetro aceptado directamente por ereport es el nivel de severidad. El texto del mensaje principal y cualquier elemento de mensaje opcional se generan llamando a funciones auxiliares, como errmsg, dentro de la llamada a ereport.

Una llamada típica a ereport podría verse así:

ereport(ERROR,
        errcode(ERRCODE_DIVISION_BY_ZERO),
        errmsg("division by zero"));

Esto especifica el nivel de severidad de error ERROR (un error común). La llamada a errcode especifica el código de error SQLSTATE utilizando una macro definida en src/include/utils/errcodes.h. La llamada a errmsg proporciona el texto del mensaje principal.

También verás con frecuencia este estilo más antiguo, con un conjunto adicional de paréntesis que rodean las llamadas a funciones auxiliares:

ereport(ERROR,
        (errcode(ERRCODE_DIVISION_BY_ZERO),
         errmsg("division by zero")));

Los paréntesis adicionales eran obligatorios antes de la versión 12 de PostgreSQL, pero ahora son opcionales.

Aquí tienes un ejemplo más complejo:

ereport(ERROR,
        errcode(ERRCODE_AMBIGUOUS_FUNCTION),
        errmsg("function %s is not unique",
               func_signature_string(funcname, nargs,
                                     NIL, actual_arg_types)),
        errhint("Unable to choose a best candidate function. "
                "You might need to add explicit typecasts."));

Esto ilustra el uso de códigos de formato para incrustar valores en tiempo de ejecución en el texto de un mensaje. Además, se proporciona un mensaje de sugerencia (hint) opcional. Las llamadas a funciones auxiliares se pueden escribir en cualquier orden, pero convencionalmente errcode y errmsg aparecen primero.

Si el nivel de severidad es ERROR o superior, ereport cancela la ejecución de la consulta actual y no regresa a quien lo llamó. Si el nivel de severidad es inferior a ERROR, ereport retorna normalmente.

Las rutinas auxiliares disponibles para ereport son:

Note

Como máximo, se debe utilizar una de las funciones errtable, errtablecol, errtableconstraint, errdatatype o errdomainconstraint en una llamada a ereport. Estas funciones existen para permitir que las aplicaciones extraigan el nombre de un objeto de base de datos asociado con la condición de error sin tener que examinar el texto del mensaje de error, que podría estar localizado. Estas funciones deben utilizarse en los reportes de error para los que es probable que las aplicaciones deseen tener un manejo automático de errores. A partir de PostgreSQL 9.3, la cobertura completa existe solo para los errores en la clase SQLSTATE 23 (violación de restricción de integridad), pero es probable que esto se amplíe en el futuro.

Existe una función más antigua, elog, que todavía se utiliza con frecuencia. Una llamada a elog:

elog(level, "cadena de formato", ...);

es exactamente equivalente a:

ereport(level, errmsg_internal("cadena de formato", ...));

Ten en cuenta que el código de error SQLSTATE siempre se establece por defecto, y la cadena del mensaje no está sujeta a traducción. Por lo tanto, elog solo debe usarse para errores internos y registros de depuración de bajo nivel. Cualquier mensaje que pueda ser de interés para los usuarios comunes debe pasar por ereport. No obstante, existen suficientes comprobaciones de errores internos de tipo no debería ocurrir (cannot happen) en el sistema como para que elog se siga utilizando ampliamente; se prefiere para esos mensajes por su simplicidad de notación.

Puedes encontrar consejos sobre cómo escribir buenos mensajes de error en Section 55.3.



[18] Es decir, el valor que estaba vigente cuando se alcanzó la llamada a ereport; los cambios de errno dentro de las rutinas de reporte auxiliares no lo afectarán. Eso no sería cierto si escribieras strerror(errno) explícitamente en la lista de parámetros de errmsg; por lo tanto, no lo hagas.