Documentação do PostgreSQL 8.0.0 | ||||
---|---|---|---|---|
Anterior | Início | Capítulo 44. Convenções de codificação do PostgreSQL | Fim | Próxima |
As mensagens de erro, de advertência e de log geradas a partir do código do servidor devem ser criadas utilizando ereport, ou seu primo mais antigo elog. A utilização desta função é suficientemente complexa para merecer uma explicação.
Existem dois elementos requeridos em todas as mensagens: o nível de severidade (indo de DEBUG até PANIC), e o texto primário da mensagem. Além desses, existem elementos opcionais, sendo o mais comum o código de identificação do erro que segue as convenções para SQLSTATE da especificação do padrão SQL. O próprio ereport é apenas uma casca de função, que existe principalmente pela comodidade sintática de fazer a geração de mensagens se parecer com uma chamada de função no código fonte C. O único parâmetro aceito diretamente pelo ereport é o nível de severidade. O texto primário da mensagem, e todos os elementos opcionais da mensagem, são gerados chamando funções auxiliares, como errmsg, dentro da chamada a ereport.
Uma chamada típica a ereport se parece com:
ereport(ERROR, (errcode(ERRCODE_DIVISION_BY_ZERO), errmsg("divisão por zero")));
Esta chamada especifica o nível de severidade do erro ERROR (um erro comum). A chamada a errcode especifica o código de erro SQLSTATE utilizando a macro definida em src/include/utils/errcodes.h. A chamada a errmsg especifica o texto primário da mensagem. Deve-se observar o conjunto extra de parênteses envolvendo as chamadas a funções auxiliares — são aborrecidos mas são sintaticamente necessários.
Abaixo está mostrado um exemplo mais complexo:
ereport(ERROR, (errcode(ERRCODE_AMBIGUOUS_FUNCTION), errmsg("a função %s não é única", func_signature_string(funcname, nargs, actual_arg_types)), errhint("Não foi possível escolher a função melhor candidata. " "Pode ser necessário adicionar conversões de tipo explícitas.")));
Este exemplo mostra a utilização dos códigos de formato para incorporar valores em tempo de execução ao texto da mensagem; também fornece uma mensagem opcional de "dica" (hint).
As rotinas auxiliares disponíveis para ereport são:
errcode(sqlerrcode) — especifica o identificador de erro SQLSTATE para a condição. Se esta rotina não for chamada, o padrão para o identificador de erro é ERRCODE_INTERNAL_ERROR quando o nível de severidade do erro for ERROR ou maior, ERRCODE_WARNING quando o nível do erro for WARNING, senão (para NOTICE e abaixo) ERRCODE_SUCCESSFUL_COMPLETION. Embora estes padrões sejam convenientes na maioria das vezes, deve-se sempre analisar se são apropriados antes de omitir a chamada a errcode().
errmsg(const char *msg, ...) — especifica o texto primário da mensagem e, possivelmente, valores em tempo de execução a serem inseridos no mesmo. As inserções são especificadas através de códigos de formato no estilo sprintf. Além dos códigos de formato padrão aceitos por sprintf, pode ser utilizado o código de formato %m para inserir a mensagem de erro retornada por strerror para o valor corrente de errno. [1] %m não requer nenhuma entrada associada na lista de parâmetros de errmsg. Deve ser observado que a cadeia de caracteres da mensagem é processada por gettext para um possível idioma, antes dos códigos de formato serem processados.
errmsg_internal(const char *msg, ...) — é o mesmo que errmsg, exceto que a cadeia de caracteres da mensagem não é incluída no dicionário de internacionalização de mensagens. Deve ser utilizada nos casos "que não podem acontecer" e, portanto, provavelmente não vale o esforço necessário para traduzi-la.
errdetail(const char *msg, ...) — produz uma mensagem opcional de "detalhe"; deve ser utilizada quando existe informação adicional, que parece não ser apropriada para ser colocada na mensagem primária. A cadeia de caracteres da mensagem é processada da mesma maneira que em errmsg.
errhint(const char *msg, ...) — produz uma mensagem opcional de "dica"; deve ser utilizada para oferecer sugestões sobre como corrigir o problema; o oposto dos detalhes dos fatos sobre o que deu errado. A cadeia de caracteres da mensagem é processada da mesma maneira que em errmsg.
errcontext(const char *msg, ...) — normalmente não é chamada diretamente a partir do conjunto de mensagens de ereport; em vez disso é utilizada nas funções de rechamada (callback) error_context_stack, para fornecer informações sobre o contexto onde o erro ocorreu, tal como o local corrente em uma função PL. A cadeia de caracteres da mensagem é processada da mesma maneira que em errmsg. Ao contrário das outras funções auxiliares, esta função pode ser chamada mais de uma vez na chamada a ereport; as cadeias de caracteres sucessivas fornecidas são concatenadas separadas pelo caractere de nova-linha.
errposition(int cursorpos) — especifica o idioma textual do erro dentro da cadeia de caracteres do comando. Atualmente é útil apenas para os erros detectados nas fases de análise léxica e sintática do processamento do comando.
errcode_for_file_access() — é uma função de conveniência que seleciona o identificador de erro SQLSTATE apropriado para uma falha em uma chamada de sistema relacionada com acesso a arquivo. Utiliza o errno salvo para determinar o código de erro a ser gerado. Geralmente deve ser utilizada em combinação com %m no texto da mensagem de erro primária.
errcode_for_socket_access() — é uma função de conveniência que seleciona o identificador de erro SQLSTATE apropriado para uma falha em uma chamada de sistema relacionada com um soquete.
Existe uma função mais antiga elog que ainda é muito utilizada. Uma chamada a elog
elog(nível, "cadeia de caracteres de formatação", ...);
é exatamente equivalente a
ereport(nível, (errmsg_internal("cadeia de caracteres de formatação", ...)));
Deve ser observado que o código de erro SQLSTATE é sempre o padrão, e que a cadeia de caracteres da mensagem não é incluída no dicionário de internacionalização de mensagens. Portanto, elog deve ser utilizada apenas para erros internos e para registro de depuração de baixo nível. Toda mensagem que possivelmente será de interesse dos usuários comuns deve ser emitida através de ereport. Apesar disso, existe no sistema um número suficiente de verificação de erros "que não podem acontecer" para que elog ainda seja muito utilizada; é preferida para estas mensagens devido à simplicidade de sua notação.
Podem ser encontrados bons conselhos sobre como escrever boas mensagens de erro na Seção 44.3.
[1] |
Ou seja, o valor corrente quando a chamada a ereport foi encontrada; mudanças em errno dentro das rotinas auxiliares não vão afetá-lo. Isto não seria verdade se fosse escrito explicitamente strerror(errno) na lista de parâmetros de errmsg; por isso, não o faça. |