Disparando e Capturando uma Exceção
Nesta etapa, você aprenderá a lidar com erros de tempo de execução, conhecidos como exceções. Uma exceção não tratada encerrará imediatamente sua função. Primeiro, você criará uma função que falha e, em seguida, a modificará para capturar a exceção de forma elegante.
Vamos criar uma função simple_divide que realiza divisão inteira. Esta função tem uma falha potencial: ela travará se você tentar dividir por zero.
CREATE OR REPLACE FUNCTION simple_divide(numerator INTEGER, denominator INTEGER)
RETURNS INTEGER AS $$
BEGIN
RETURN numerator / denominator;
END;
$$ LANGUAGE plpgsql;
Primeiro, chame a função com entradas válidas para confirmar que ela funciona corretamente:
SELECT simple_divide(10, 2);
A saída será o resultado da divisão:
simple_divide
---------------
5
(1 row)
Agora, chame a função com um denominador zero para acionar uma exceção:
SELECT simple_divide(10, 0);
Este comando falhará e retornará uma mensagem de erro. A execução da função é abortada.
ERROR: division by zero
CONTEXT: PL/pgSQL function simple_divide(integer,integer) line 3 at RETURN
Esta é uma exceção não tratada. Para evitar que a função trave, você pode usar um bloco EXCEPTION. Vamos criar uma nova função safe_divide que inclua tratamento de erros.
CREATE OR REPLACE FUNCTION safe_divide(numerator INTEGER, denominator INTEGER)
RETURNS INTEGER AS $$
BEGIN
RETURN numerator / denominator;
EXCEPTION
WHEN division_by_zero THEN
RAISE NOTICE 'Error: Cannot divide by zero.';
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
Veja como o bloco EXCEPTION funciona:
BEGIN...END;: Isso define um bloco de código.
EXCEPTION: Esta palavra-chave inicia a seção de tratamento de exceções.
WHEN division_by_zero THEN: Isso especifica que o código a seguir deve ser executado apenas quando ocorrer um erro division_by_zero.
- O código dentro do manipulador emite um aviso (notice) e retorna
NULL em vez de travar.
Agora, chame a nova função safe_divide com um denominador zero:
SELECT safe_divide(10, 0);
Desta vez, a função não trava. Ela captura a exceção, exibe seu aviso personalizado e retorna NULL.
NOTICE: Error: Cannot divide by zero.
safe_divide
-------------
(1 row)
Você capturou com sucesso uma exceção específica e controlou a saída da função.