Introduzimos recentemente um novo mecanismo de tratamento de erros utilizando o novo comando throw().
Isso marcou o primeiro passo para um novo sistema de tratamento de erros, posicionado o mais próximo possível do código que os gera.
Na próxima fase com 4D v20 R4, estamos a expandir esta abordagem para intercetar erros durante a execução de expressões.
Vamos nos aprofundar nos detalhes.
try(), uma nova palavra-chave útil
Com a introdução de 4D v20 R4, os programadores podem agora aceder a uma nova palavra-chave útil: Try(Expression). A palavra-chave Try() permite que os desenvolvedores executem uma expressão entre parênteses e interceptem qualquer erro lançado durante sua execução. Esses erros podem ser tratados usando o comando Last errors imediatamente após a execução da expressão. Isto permite-lhe definir a sua gestão de erros o mais próximo possível do código que os gerou e, eventualmente, utilizar variáveis locais.
Exemplos de cenários antes de explicações pormenorizadas
Divisão por zero
Considere um cenário simples: divisão por zero. O exemplo seguinte demonstra um método de divisão euclidiana que lança um erro e devolve arbitrariamente zero se o divisor for zero. Com Try(), os programadores podem gerir os erros de forma mais elegante:
#DECLARE($dividend: Real; $divisor: Real)->$result: Real
If ($divisor=0)
$result :=0
throw (-12345; "Divisão por zero!")
Else
$result :=($dividend/$divisor)
End if
$result:=Try(division($dividend; $divisor))
If (Last errors#Null)
// Error management
logErrors (Last errors)
End if
ACEDER a um documento
Gerenciar erros ao acessar um documento se torna mais simples se o documento não existe.
Para evitar que o diálogo de erro 4D seja exibido, um manipulador de erros precisa ser instalado, e o código de gerenciamento de erros precisa ser escrito dentro desse manipulador de erros:
$previousErrorHandler:=Method called on error
ON ERR CALL ("errorOpenDoc")
var $fileHandle : 4D.FileHandle:=File($path).open()
If ($fileHandle#Null)
ON ERR CALL ("errorReadDoc")
$text :=$fileHandle.readText()
If (Last errors#Null)
$text :="Erro ao ler o ficheiro"
End if
End if
ON ERR CALL ($previousErrorHandler)
Com a palavra-chave Try(), tudo pode ser escrito na mesma secção de código, acedendo a variáveis locais e simplificando assim a legibilidade:
var $fileHandle : 4D.FileHandle:=Try(File($path).open())
If ($fileHandle#Null)
$text :=Try($fileHandle.readText()) || "Erro ao ler o ficheiro"
End if
Função de gravação ORDA
Outro caso de uso robusto envolve a função ORDA save(), que pode gerar erros previsíveis e imprevisíveis.
Os erros previsíveis, como o bloqueio de entidade, podem ser tratados diretamente através do atributo de sucesso do resultado. No entanto, erros imprevisíveis, como duplicatas de chave primária, requerem um manipulador de erros instalado com o comando ON ERR CALL caso contrário, o diálogo de erro 4D seria exibido:
var $customer : cs.CustomerEntity
// Do something with the $customer entity
$previousErrorHandler :=Method called on error
ON ERR CALL ("errorSaveManagement")
$result :=$customer.save()
ON ERR CALL ($previousErrorHandler)
If (Not($result.success))
Case of
: ($result.status=3)
// Locked entity management
: ($result.status=4)
// Other error management
End case
End if
Mas agora, a palavra-chave Try() torna-se um aliado valioso no tratamento de erros previsíveis e imprevisíveis sem mostrar o diálogo de erro 4D:
var $customer : cs.CustomerEntity
// Do something with the $customer entity
$result :=Try($customer.save())
If (Not($result.success))
Case of
: ($result.status=3)
// Locked entity management
: ($result.status=4)
// Other error management
End case
End if
Execução de expressões
A palavra-chave Try() aceita qualquer expressão 4D entre parênteses, quer se trate de variáveis, atribuições, métodos, funções, etc. Em caso de erro, o fluxo de execução pára e retorna à última palavra-chave Try() encontrada (a primeira encontrada de volta na pilha de chamadas). Como resultado, basta verificar a pilha de erros após a execução da expressão para saber se ocorreram erros.
Observe que, se um erro for gerado usando o comando throw() no modo diferido, o fluxo de execução continua até ao fim da execução do método/função atual, proporcionando uma forma simples de gerir a propagação de erros.
Resultados
Se a execução for bem sucedida, Try() devolve o resultado da expressão.
Em caso de erro, devolve o último resultado da expressão ou ‘undefined’ se não estiver disponível.
Se a expressão não definir nenhum resultado (por exemplo, um método ou comando sem resultado), a palavra-chave try retorna ‘undefined’.
Sobre a pilha de erros
A pilha de erros atual é limpa antes de a expressão ser executada, oferecendo um quadro limpo para o tratamento de erros no contexto Try(). Os erros encontrados durante a execução da expressão são adicionados à pilha de erros, fornecendo aos desenvolvedores informações abrangentes para depuração.
Tratamento de erros
Se nenhum manipulador de erros atual for definido usando o comando ON ERR CALL a caixa de diálogo de erro não interromperá a experiência do utilizador utilizando Try().
Os manipuladores de erros globais e locais definidos antes de entrar no bloco Try() não serão chamados, garantindo uma separação limpa entre o contexto try e o resto do código.
Se a expressão definir um manipulador de erros global ou local para o banco de dados atual, ele será chamado quando ocorrer um erro durante a execução.
Explore novos horizontes no gerenciamento de erros
Este novo recurso abre um mundo de possibilidades para o gerenciamento de erros. Mas é apenas o segundo passo na nova era de gerenciamento de erros 4D que abre caminho para blocos try-catch de várias linhas!
Partilhe as suas ideias e experiências no nosso fórum e diga-nos o que pensa sobre esta nova funcionalidade.
Boa programação!