Catching Exceptions in PL/pgSQL
In this step, you will learn how to catch exceptions in PL/pgSQL using the EXCEPTION
block. Exception handling allows you to handle errors gracefully, preventing your function from crashing and providing informative error messages.
The basic structure of an exception block is:
BEGIN
-- Code that might raise an exception
EXCEPTION
WHEN exception_name THEN
-- Code to handle the exception
END;
The BEGIN
and END
keywords define the block of code where exceptions might occur. The EXCEPTION
keyword introduces the exception handling section. The WHEN
clause specifies the type of exception to catch, and the code following THEN
is executed when that exception occurs.
Let's create a function that attempts to divide a number by zero and catches the resulting exception. We'll name it safe_divide
.
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 'Division by zero occurred!';
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
This function takes two integer arguments, numerator
and denominator
. Inside the BEGIN
block, it attempts to divide the numerator
by the denominator
. If the denominator
is zero, a division_by_zero
exception will be raised. The EXCEPTION
block catches this exception, raises a notice, and returns NULL
.
Now, let's call the function with a divisor of zero:
SELECT safe_divide(10, 0);
You should see output similar to this:
NOTICE: Division by zero occurred!
safe_divide
-------------
NULL
(1 row)
The NOTICE
message "Division by zero occurred!" is displayed, and the function returns NULL
, indicating that the exception was caught and handled.
Now, let's call the function with valid inputs:
SELECT safe_divide(10, 2);
You should see output similar to this:
safe_divide
-------------
5
(1 row)
The function returns the correct quotient, 5, without raising any exceptions.
You can also catch other types of exceptions, such as numeric_value_out_of_range
, null_value_not_allowed
, and others
. The others
exception handler catches any exception that is not explicitly handled by a previous WHEN
clause.
Let's modify the function to catch any exception and return -1:
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 'Division by zero occurred!';
RETURN NULL;
WHEN OTHERS THEN
RAISE NOTICE 'An unexpected error occurred: %', SQLERRM;
RETURN -1;
END;
$$ LANGUAGE plpgsql;
In this modified function, if any exception other than division_by_zero
occurs, the OTHERS
exception handler will be executed. SQLERRM
is a built-in variable that contains the error message associated with the exception.