Gestão de erros
O manejo de erros é o processo de antecipar e responder aos erros que possam ocorrer em sua aplicação. 4D oferece assistência completa à detecção e notificação de erros no tempo de execução, assim como a análise de suas condições.
Manejo de erros responde à duas necessidades principais:
- descobrir e consertar erros potenciais e bugs no código durante a fase de desenvolvimento,
- capturando e recuperando de erros inesperados em aplicativos implementados; em particular, você pode substituir caixas de diálogo de erro do sistema (disco cheio, arquivo em falta, etc.) com sua própria interface.
Basicamente, há duas maneiras de lidar com erros em 4D. Pode:
- instalar un método de gestión de errores, o
- use uma palavra-chave
Try()
ou uma estruturaTry/Catch
antes de pedaços de código que chamem uma função, método ou expressão que possam lançar um erro.
> > É recomendado instalar um método de gerenciamento de erros em 4D Server, para todos os códigos rodando no servidor. Quando o servidor 4D não estiver executando headless (ou seja, inicializado com sua [janela de administração](.. ServerWindow/overview.md)), este método evitaria caixas de diálogo inesperadas a serem exibidas na máquina do servidor. No modo headless, erros são registrados no arquivo 4DDebugLog para análise posterior.
Erro ou status
Muitas funções de classe 4D, tais como entity.save()
ou transporter.send()
, retornam um objeto de status. Este objeto é usado para armazenar erros "previsíveis" no contexto de tempo de execução, por exemplo, senha inválida, entidade bloqueada, etc., que não interrompem a execução do programa. Esta categoria de erros pode ser tratada por código normal.
Outros erros "imprevisíveis" incluem erro de gravação em disco, falha de rede, ou em geral qualquer interrupção inesperada. Esta categoria de erros gera exceções e precisa ser tratada através de um método de manipulação de erros ou uma palavra-chave Try()
.
Instalação de um método de gestão de erros
Em 4D, todos os erros podem ser capturados e tratados por métodos específicos do projeto, denominados métodos de tratamento de erros (ou captura de erros).
Uma vez instalados, os manipuladores de erros são automaticamente chamados em modo interpretado ou compilado em caso de erro na aplicação 4D ou num dos seus componentes. Um manipulador de erros diferente pode ser chamado em função do contexto de execução (ver abaixo).
Para instalar um método de projeto de manipulação de erros, você só precisa chamar o [LIGA DE ERRO CALL
](https://doc.4d. comando/4dv19/help/command/en/page155.html) com o nome do método do projeto e (opcionnalmente) escopo como parâmetros. Por exemplo:
ON ERR CALL("IO_ERRORS") //Instala o método de gestão de erros
Para deixar de detectar erros para um contexto de execução e devolver o controle, chame ON ERR CALL
com uma string vazia:
ON ERR CALL("";ek local) // dá o controle para o processo local
O comando Método chamado erro
permite que você saiba o nome do método instalado por ON ERR CALL
para o processo atual. É particularmente útil no contexto dos componentes porque permite mudar temporariamente e depois restaurar o método de captura de erros do banco de dados local:
$methCurrent:=Método chamado em caso de erro(ek local)
ON ERR CALL("NewMethod";ek local)
//Se o documento não pode ser aberto, um erro é gerado
$ref:=Abrir documento("MyDocument")
//Reinstalação do método anterior
ON ERR CALL($methCurrent;ek local)
Alcance e componentes
Um método de tratamento de erros pode ser definido para diferentes contextos de execução:
- para o processo atual- um manipulador de erros local será chamado apenas para erros que ocorreram no processo atual do projeto atual,
- para o aplicativo inteiro - um manipulador de erros global será chamado para todos os erros que ocorreram no contexto de execução do aplicativo do projeto atual,
- dos componentes - esse manipulador de erros é definido em um projeto host e será chamado para todos os erros que ocorreram nos componentes quando eles ainda não foram capturados por um manipulador de componentes.
Exemplos:
ON ERR CALL("IO_Errors";ek local) //Instala um método local de tratamento de erros ON ERR CALL("globalHandler";ek global) //Instala um método global de tratamento de erros ON ERR CALL("componentHandler";ek erros de componentes) //Instala um método de tratamento de erros de componentes
Pode instalar um gerenciador de erros global que servirá como "fallback" e métodos de erros locais específicos para certos processos. Um manipulador de erros global é também útil no servidor para evitar diálogos de erro no servidor quando executado com interface.
Pode definir um único método de captura de erros para toda a aplicação ou diferentes métodos por módulo de aplicação. Entretanto, apenas um método pode ser instalado por processo.
Quando ocorre um erro, apenas um método é chamado, como descrito no diagrama seguinte:
Manejo de erros dentro do método
Dentro de um método de erro personalizado, você tem acesso a várias informações que ajudarão você a identificar o erro:
-
variáveis de sistema dedicadas:
Erro
(inteiro longo): código de erroError line
(entero largo): número de línea del método que ha provocado el errorLinha de erro
(longin): número de linha no método que desencadeou o erroFórmula de erro
(texto): fórmula do código 4D (texto bruto) que está na origem do erro.
O 4D mantém automaticamente uma série de variáveis chamadas variáveis sistema, que respondem a diferentes necessidades. Ver o manual da linguagem 4D*.
- o comando
Últimos erros
que retorna uma coleção da pilha de erros atual que ocorreu na aplicação 4D. Você também pode usar o comandoGET LAST ERROR STACK
que retorna a mesma informação que as matrizes. - o comando
Get call chain
que retorna uma coleção de objetos que descrevem cada etapa da cadeia de chamadas de métodos no processo atual.
Exemplo
Aqui está um sistema de gestão de erros simples:
//instalar o método de gestão de erros
ON ERR CALL("errorMethod")
//... executar o código
ON ERR CALL("") //retorna o controle para 4D
// Método do projeto errorMethod
If(Error#1006) //isso não é uma interrupção do usuário
ALERT("The error "+String(Error)+" occurred". O código em questão é: \""+Error formula+"\"")
End if
Utilizar um método de gestão de erro vazio
Se quiser que a caixa de diálogo fique escondida, pode instalar um método de gestão de erros vazio. A variável Error
do sistema pode ser testada em qualquer método, ou seja, fora do método de gestão de erros:
ERR CALL("emptyMethod") //vazityMethod existe mas está vazio
$doc:=Open document( "myFile. xt")
Se (Error=-43)
├ALERT("Arquivo não encontrado.")
Finalize se
NO ERR CALL("")
Try(expression)
A instrução Try(expression)
permite que você teste uma expressão de linha única no contexto de execução atual (incluindo, em particular, valores variáveis locais) e para interceptar erros que ele lança para que a caixa de diálogo de erro 4D não seja exibida. O uso de Try(expression)
oferece uma maneira fácil de tratar casos de erro simples com um número muito baixo de linhas de código e sem exigir um método de tratamento de erros.
Se você quiser tentar um código mais complexo do que uma expressão de uma única linha, você pode considerar usar uma estrutura Try/Catch
.
A sintaxe formal da instrução Try(expression)
é:
Try (expression) : any | Undefined
expressão pode ser qualquer expressão válida.
Se ocorrer um erro durante sua execução, ele será interceptado e nenhuma caixa de diálogo de erro será exibida, independentemente de um [método de tratamento de erros] (#installing-an-error-handling-method) ter sido instalado ou não antes da chamada para Try()
. Se expressão retorna um valor, Try()
retorna o último valor avaliado, caso contrário, ele retorna Undefined
.
Você pode lidar com o(s) erro(s) usando o comando Últimos erros
. Se a expressão lançar um erro em uma pilha de chamadas Try()
, o fluxo de execução será interrompido e retornará ao último Try()
executado (o primeiro encontrado na pilha de chamadas).
Se um método de tratamento de erros for instalado por expressão, ele é chamado em caso de erro.
Exemplos
- Você quer exibir o conteúdo de um arquivo se o arquivo pode ser aberto sem erro e se o seu conteúdo pode ser lido. Você pode escrever:
var $text : Text
var $file : 4D.File := File("/RESOURCES/myFile.txt")
var $fileHandle : 4D.FileHandle := Try($file.open())
If ($fileHandle # Null)
$text:=Try($fileHandle.readText()) || "Erro ao ler o arquivo"
End if
- Você deseja tratar o erro de divisão por zero. Nesse caso, você deseja retornar 0 e lançar um erro:
function divide( $p1: real; $p2: real)-> $result: real
if ($p2=0)
$result:=0 //apenas por claridade (0 se o padrão for reais)
throw(-12345; "Division by zero")
else
$result:=$p1/$p2
end if
function test()
$result:=Try(divide($p1;$p2))
If (Last errors # null)
ALERT("Error")
End if
- Você deseja lidar com erros previsíveis e não previsíveis:
var $e:=ds.Employee.new()
$e.name:="Smith"
$status:=Try($e.save()) // Captura de erros previsíveis e não previsíveis
If ($status.success)
ALERT( "Success")
Else
ALERT( "Error: "+JSON Stringify($status.errors))
End if
Try...Catch...End try
A estrutura Try...Catch...End try
permite que você teste um bloco de código em seu contexto de execução atual (incluindo, em particular, os valores de variáveis locais) e intercepte os erros que ele lança, para que a caixa de diálogo de erro do 4D não seja exibida.
Ao contrário da palavra-chave Try(expressão)
que avalia uma expressão de linha única, a Experimente...Catch... a estrutura nd try
permite que você avalie qualquer bloco de código, do mais simples para o mais complexo, sem exigir um método de manipulação de erro. Além disso, o bloco Catch
pode ser usado para tratar o erro de qualquer forma personalizada.
A sintaxe formal da estrutura Try...Catch...End try
é:
Try
statement(s) // Código a ser avaliado
Catch
statement(s) // Código a ser executado em caso de erro
End try
O código colocado entre as palavras-chave Try
e Catch
é executado primeiro e, em seguida, o fluxo depende do(s) erro(s) encontrado(s) durante essa execução.
- Se nenhum erro for lançado, a execução do código continuará após a palavra-chave
End try
correspondente. O código colocado entre as palavras-chaveCatch
eEnd try
não é executado. - Se a execução do bloco de código lançar um erro não diferido, o fluxo de execução é interrompido e o bloco de código
Catch
correspondente é executado. - Se o bloco de execução de código lançar um erro atrasado, o fluxo de execução continua até o final do bloco
Try
e, em seguida, executa o bloco de códigoCatch
correspondente.
Se um erro deferred for lançado fora do bloco Try
, a execução do código continua até o final do método ou função.
Para obter mais informações sobre erros deferred e non-deferred, consulte a descrição do comando throw
.
No bloco de código Catch
, você pode lidar com o(s) erro(s) usando comandos padrão de tratamento de erros. A função Últimos Erros
contém a última coleção de erros. Você pode declarar um método de tratamento de erros neste bloco de código, caso em que ele é chamado em caso de erro (caso contrário, a caixa de diálogo de erro do 4D é exibida).
Se um método de tratamento de erros for instalado no código colocado entre as palavras-chave Try
e Catch
, ele é chamado em caso de erro.
Exemplo
A combinação de transações e estruturas Try...Catch...End try
permite escrever código seguro para recursos críticos.
Function createInvoice($customer : cs.customerEntity; $items : Collection; $invoiceRef : Text) : cs.invoiceEntity
var $newInvoice : cs.invoiceEntity
var $newInvoiceLine : cs.invoiceLineEntity
var $item : Object
ds.startTransaction()
Try
$newInvoice:=This.new()
$newInvoice.customer:=$customer
$newInvoice.invoiceRef:=$invoiceRef
For each ($item; $items)
$newInvoiceLine:=ds.invoiceLine.new()
$newInvoiceLine.item:=$item.item
$newInvoiceLine.amount:=$item.amount
$newInvoiceLine.invoice:=$newInvoice
//chamar outras funções específicas para validar a linha de fatura
$newInvoiceLine.save()
End for each
$newInvoice.save()
ds.validateTransaction()
Catch
ds.cancelTransaction()
ds.logErrors(Last errors)
$newInvoice:=Null
End try
return $newInvoice