Curso de Ruby - Tratamento de Exceções
O tratamento de erros é fundamental para garantir que seu programa lide com situações inesperadas de forma controlada, sem travar.
O que são Exceções?
Exceções são erros que ocorrem durante a execução do programa. Quando uma exceção é levantada (ou seja, ocorre um erro), ela interrompe o fluxo normal do programa. No entanto, podemos capturar essas exceções e tratá-las de maneira adequada para evitar que o programa falhe.
Como Funciona o Tratamento de Exceções em Ruby?
Ruby utiliza os blocos begin
, rescue
, else
, e ensure
para tratar erros. A estrutura básica de tratamento de exceções é:
begin
# Código que pode gerar erro
rescue TipoDeErro => e
# Código que trata o erro
else
# Código que é executado se não houver erro
ensure
# Código que é sempre executado, independentemente de erro
end
Componentes:
begin
: Inicia o bloco de código onde o erro pode ocorrer.rescue
: Captura o erro e permite tratá-lo.else
: (Opcional) Executado se nenhum erro ocorrer no blocobegin
.ensure
: (Opcional) Executado sempre, independentemente de erro ou não.
Exemplo Básico de Tratamento de Exceção
Exemplo 1: Capturando Exceções
begin
puts "Tentando dividir por zero..."
resultado = 10 / 0
rescue ZeroDivisionError => e
puts "Erro: #{e.class} - #{e.message}"
end
Saída:
Tentando dividir por zero...
Erro: ZeroDivisionError - divided by 0
Detalhes:
- Quando o erro
ZeroDivisionError
ocorre, o código dentro derescue
é executado. - O objeto
e
contém informações sobre o erro, comoe.class
(tipo de erro) ee.message
(mensagem do erro).
Capturando Múltiplos Tipos de Erros
Você pode capturar diferentes tipos de erros em um único bloco rescue
:
Exemplo 2: Capturando múltiplos erros
begin
puts "Tentando acessar um arquivo..."
file = File.open("arquivo_inexistente.txt")
rescue ZeroDivisionError => e
puts "Erro de divisão: #{e.message}"
rescue IOError => e
puts "Erro de arquivo: #{e.message}"
end
Saída:
Erro de arquivo: No such file or directory @ rb_sysopen - arquivo_inexistente.txt
Detalhes:
- O bloco
rescue
pode ser usado para capturar múltiplos tipos de erros, cada um com seu próprio tratamento. ZeroDivisionError
eIOError
são exemplos de diferentes tipos de exceções que podemos capturar e tratar separadamente.
Bloco else
O bloco else
é executado apenas se nenhum erro ocorrer no bloco begin
.
Exemplo 3: Usando else
begin
puts "Tentando realizar uma operação..."
resultado = 10 / 2
rescue ZeroDivisionError => e
puts "Erro: #{e.message}"
else
puts "Operação bem-sucedida! Resultado: #{resultado}"
end
Saída:
Tentando realizar uma operação...
Operação bem-sucedida! Resultado: 5
Detalhes:
- Se o código dentro de
begin
não gerar erro, o blocoelse
é executado.
Bloco ensure
O bloco ensure
é executado sempre, independentemente de erro ou não. Isso é útil quando você precisa garantir que um certo código seja executado, como o fechamento de arquivos ou a liberação de recursos.
Exemplo 4: Usando ensure
begin
puts "Abrindo arquivo..."
file = File.open("arquivo.txt", "w")
file.puts "Escrevendo no arquivo"
rescue IOError => e
puts "Erro de arquivo: #{e.message}"
ensure
puts "Fechando arquivo..."
file.close if file
end
Saída:
Abrindo arquivo...
Fechando arquivo...
Detalhes:
- O código dentro de
ensure
sempre será executado, mesmo que ocorra um erro no blocobegin
.
Levantando Exceções Manualmente
Em Ruby, você também pode levantar exceções manualmente usando a palavra-chave raise
.
Exemplo 5: Levantando uma Exceção
def dividir(a, b)
raise "Divisão por zero não permitida" if b == 0
a / b
end
begin
puts dividir(10, 0)
rescue => e
puts "Erro: #{e.message}"
end
Saída:
Erro: Divisão por zero não permitida
Detalhes:
- A função
dividir
lança uma exceção com a mensagem “Divisão por zero não permitida” se o divisor for zero.
Exceções Personalizadas
Você também pode criar suas próprias exceções definindo novas classes de erro.
Exemplo 6: Exceções Personalizadas
class MeuErro < StandardError; end
def fazer_algo
raise MeuErro, "Algo deu errado!"
end
begin
fazer_algo
rescue MeuErro => e
puts "Erro personalizado: #{e.message}"
end
Saída:
Erro personalizado: Algo deu errado!
Detalhes:
- Criamos uma classe de erro personalizada (
MeuErro
) que herda deStandardError
. - Agora podemos lançar e capturar exceções desse tipo em nosso código.
Resumo e Boas Práticas
- Use
begin
erescue
para capturar exceções e garantir que seu programa não quebre com erros inesperados. - Evite capturar erros genéricos como
rescue => e
, a menos que seja realmente necessário. Prefira capturar erros específicos. - Use
ensure
para garantir que recursos (como arquivos ou conexões) sejam sempre fechados, independentemente de erros. - Levante exceções quando você precisar sinalizar que algo deu errado no seu código, especialmente em métodos.
Exercício
Agora é sua vez! 💪
1️⃣ Crie um método que recebe um número e tenta dividi-lo por outro número. Se o divisor for 0, levante uma exceção personalizada informando que a divisão por zero não é permitida.
2️⃣ Escreva um programa que tenta abrir um arquivo e, caso o arquivo não exista, mostre uma mensagem de erro. Certifique-se de sempre fechar o arquivo no bloco ensure
.
Se quiser, tente resolver e envie nos comentários seus códigos e suas respostas para analisarmos juntos! 🚀
Próxima aula - Programação Orientada a Objetos em Ruby