Tratamento de Exceções F#
Como desenvolvedor, usar o tratamento de exceção do F# é um aspecto importante da escrita de código robusto. O tratamento de exceções permite lidar com erros inesperados e exceções que podem ocorrer durante a execução de seu programa.
Neste artigo, exploraremos as práticas recomendadas de manipulação de exceção F# e forneceremos dicas sobre como gerar e capturar exceções, lidar com diferentes tipos de exceções e práticas recomendadas quando se trata de escrever um código de manipulação de exceção que seja eficiente, sustentável e eficaz.
Compreendendo exceções em F#
Em F#, as exceções são geradas quando ocorre um erro durante a execução de um programa.
Uma exceção é um evento de tempo de execução que interrompe o fluxo normal de execução do programa e pode ocorrer por vários motivos, como entrada inválida, comportamento inesperado ou estado inesperado.
Quando uma exceção é gerada, o fluxo normal do programa é interrompido e o tempo de execução procura um manipulador de exceção que possa lidar com a exceção. Se um manipulador de exceção apropriado não for encontrado, o programa será encerrado.
O conceito de exceção é o termo usado para descrever um problema que ocorre quando um programa está sendo executado. Exceções de F# são geradas quando um programa está sendo executado quando uma circunstância excepcional surge durante a execução do programa, como dividir por zero quando o programa está em execução.
O uso de exceções fornece um método pelo qual uma parte do programa pode transferir o controle para outra parte.
As seguintes construções estão disponíveis para lidar com exceções em F# :
Construir | Descrição |
aumentar expr | A exceção fornecida é levantada. |
falha com expr | A exceção System.Exception é levantada. |
tente expr com regras | Pegue as expressões correspondentes de acordo com as regras do padrão. |
tente expr finalmente expr | A expressão final é definida para ser executada tanto no caso de uma computação bem-sucedida quanto no caso de uma exceção. |
| |
Uma regra de exceção que corresponde ao tipo de exceção especificado pela estrutura .NET. |
| |
A regra vincula o nome “e” ao valor de objeto de um objeto de exceção que corresponda ao tipo de exceção .NET fornecido. |
| Falha(mensagem) → expr | Uma regra que corresponde a uma exceção F# de transporte de dados que foi fornecida. |
| exn → expr | Uma regra de exceção que corresponde a qualquer exceção e vincula o nome exn ao valor do objeto de exceção dessa exceção. |
| exn quando expr → expr | Uma regra de correspondência de exceção que liga o nome exn ao valor do objeto de exceção sob as condições dadas . |
Para entender como o Tratamento de Exceções funciona, vamos começar com a sintaxe básica.
Sintaxe
No F#, a sintaxe para lidar com exceções é a seguinte:
exception exception-type of argument-type
Onde,
- tipo de exceção introduz um novo tipo de exceção em F#.
- tipo de argumento esse tipo pode ser especificado por tipo de argumento ao gerar uma exceção.
- As tuplas podem ser usadas para o tipo de argumento quando vários argumentos são necessários.
F# usa a expressão try…with para lidar com exceções.
Aqui está a sintaxe para um try … com expressão:
try expression1 with | pattern1 -> expression2 | pattern2 -> expression3 ...
A expressão try…finally pode ser usada para executar código de limpeza mesmo se uma exceção for lançada por um bloco de código no meio do bloco.
Try … finalmente é expresso usando a seguinte sintaxe:
try expression1 finally expression2
Quando ocorre um erro ou condição excepcional, a função aumentar é usada para notificar o usuário. Como parte do objeto de exceção, as informações sobre o erro também são capturadas.
A sintaxe da função raise pode ser resumida da seguinte forma:
raise (expression)
As exceções F# são geradas pela função failwith.
Sua sintaxe é a seguinte:
failwith error-message-string
Uma exceção de argumento é gerada pela função invalidArg.
invalidArg parameter-name error-message-string
Dividir por exceção de zero
Example:
Ao compilar o programa, ele imprime o seguinte:
FABLE: Cannot type test (evals to false): System.DivideByZeroException
Erro de tipo
Aqui está um exemplo:
Example:
E a saída será a seguinte:
Error1 Equal Number Error Error2 Error Not detected 22
Tratamento de exceções aninhadas
Este exemplo ilustra como lidar com exceções aninhadas da seguinte maneira:
Example:
Imprime a seguinte saída:
Result: 5 No exception in inner try block Outer exception: Attempted to divide by zero.
Falha com função
Abaixo está um exemplo que cumprimenta o usuário se o nome corresponder, caso contrário, ele lançará uma exceção:
Example:
E a saída será:
Caught exception: Unknown person
Exceção invalidArg
InvalidArg gera uma exceção quando encontra um argumento inválido. Isso pode ser demonstrado pelo seguinte programa:
Example:
E o resultado será:
Tuesday Friday Unhandled Exception: System.ArgumentException: You have entered 8. Parameter name: day at Main.findDay (System.Int32 day) [0x00028] in <643d27b54fc9e525a7450383b5273d64>:0 at <StartupCode$main>.$Main.main@ () [0x000d1] in <643d27b54fc9e525a7450383b5273d64>:0 [ERROR] FATAL UNHANDLED EXCEPTION: System.ArgumentException: You have entered 8. Parameter name: day at Main.findDay (System.Int32 day) [0x00028] in <643d27b54fc9e525a7450383b5273d64>:0 at <StartupCode$main>.$Main.main@ () [0x000d1] in <643d27b54fc9e525a7450383b5273d64>:0
Exemplo de Explicação:
Temos uma lista de dias chamada days com elementos que representam os nomes dos dias da semana. Também temos uma função chamada findDay que recebe um argumento inteiro day , que representa o dia da semana (1 para domingo, 2 para segunda-feira e assim por diante).
Dentro da função findDay, primeiro verificamos se o valor do dia é maior que 7 ou menor que 1 usando uma instrução if . Se for, usamos a função invalidArg para gerar uma exceção com a mensagem de erro “Você digitou x”. onde x é o valor do dia formatado como uma string usando a função sprintf .
Caso contrário, se day for um valor válido entre 1 e 7, usaremos a matriz days para procurar o nome do dia correspondente usando a sintaxe de indexação days.[day – 1] , onde day – 1 é usado para converter o valor do dia para o índice baseado em zero do array .
Por fim, imprimimos o nome do dia retornado pela função findDay para três valores de dia diferentes (3, 6 e 8) usando instruções printfn.
Observe que a função findDay pode gerar uma exceção se um valor de dia inválido for passado, e essa exceção pode ser capturada e tratada usando técnicas apropriadas de tratamento de erros, como um bloco try-with .
Você pode ajudar outras pessoas a aprender sobre o poder e a natureza flexível do tratamento de exceções do F# compartilhando nosso artigo nas mídias sociais abaixo. Isso permitirá que eles criem aplicativos dinâmicos e interativos.
Práticas recomendadas de exceção do F#
Para escrever um código robusto em F#, é importante seguir as práticas recomendadas para manipulação de exceção.
Aqui estão algumas diretrizes a serem lembradas ao lidar com exceções em seu código F#:
- Geralmente não é recomendado capturar exceções genéricas, como System.Exception, pois pode dificultar a identificação e correção de problemas em seu código. Em vez disso, capture exceções específicas que você espera que sejam geradas e trate-as de acordo. Isso permite que você forneça mensagens de erro significativas e tome as ações apropriadas com base na exceção específica que ocorreu.
- O código de tratamento de exceção deve ser conciso e focado no tratamento da exceção em questão. Evite adicionar lógica desnecessária ou operações complexas no código de tratamento de exceção, pois isso pode dificultar a compreensão e a manutenção. Mantenha o código no bloco with mínimo e concentre-se em lidar com a exceção e fornecer feedback apropriado ao usuário.
- Engolir exceções, o que significa capturar uma exceção e não realizar nenhuma ação, pode ocultar possíveis problemas em seu código e dificultar o diagnóstico e a correção de problemas. Em vez de simplesmente ignorar as exceções, considere registrá-las ou exibir mensagens de erro apropriadas para alertar os usuários sobre o problema.
- O F# fornece recursos avançados de correspondência de padrão que podem ser usados para lidar com diferentes tipos de exceções de maneira diferente. Você pode usar correspondência de padrão para corresponder a tipos de exceção, propriedades ou dados personalizados associados à exceção. Isso permite que você forneça tratamento de erro personalizado com base na exceção específica que ocorreu.
- Em alguns casos, usar tipos de resultado, como Result <'T, 'TError> , pode ser uma maneira mais funcional de lidar com erros no código F#. Os tipos de resultado permitem que você represente explicitamente casos de sucesso e falha nos valores de retorno das funções, sem usar exceções. Isso pode levar a um código mais previsível e fácil de entender, especialmente em paradigmas de programação funcional.
Conclusão
A manipulação de exceção F# é um aspecto crítico da escrita de código robusto e confiável. Seguindo as melhores práticas para tratamento de exceções, como ser específico na captura de exceções, manter o código de tratamento de exceções focado, evitar engolir exceções, usar correspondência de padrões, considerar tipos de resultados, lidar com exceções em níveis apropriados de abstração e usar registro e monitoramento para rastreamento de erros , você pode efetivamente lidar com exceções e criar aplicativos mais resilientes e estáveis. Lembre-se de testar exaustivamente seu código de tratamento de exceção para garantir sua exatidão. Com o tratamento cuidadoso de exceções, você pode melhorar a estabilidade e a confiabilidade de seu código F#, proporcionando uma melhor experiência para seus usuários e tornando seus aplicativos mais robustos.