Home Explore Blog CI



postgresql

36th chunk of `doc/src/sgml/plpgsql.sgml`
2ac6289e807df60199f843c0cca5cd6bd1e70f44f36ef9f00000000100000fb1

     <primary>exceptions</primary>
     <secondary>in PL/pgSQL</secondary>
    </indexterm>

    <para>
     By default, any error occurring in a <application>PL/pgSQL</application>
     function aborts execution of the function and the
     surrounding transaction.  You can trap errors and recover
     from them by using a <command>BEGIN</command> block with an
     <literal>EXCEPTION</literal> clause.  The syntax is an extension of the
     normal syntax for a <command>BEGIN</command> block:

<synopsis>
<optional> &lt;&lt;<replaceable>label</replaceable>&gt;&gt; </optional>
<optional> DECLARE
    <replaceable>declarations</replaceable> </optional>
BEGIN
    <replaceable>statements</replaceable>
EXCEPTION
    WHEN <replaceable>condition</replaceable> <optional> OR <replaceable>condition</replaceable> ... </optional> THEN
        <replaceable>handler_statements</replaceable>
    <optional> WHEN <replaceable>condition</replaceable> <optional> OR <replaceable>condition</replaceable> ... </optional> THEN
          <replaceable>handler_statements</replaceable>
      ... </optional>
END;
</synopsis>
    </para>

    <para>
     If no error occurs, this form of block simply executes all the
     <replaceable>statements</replaceable>, and then control passes
     to the next statement after <literal>END</literal>.  But if an error
     occurs within the <replaceable>statements</replaceable>, further
     processing of the <replaceable>statements</replaceable> is
     abandoned, and control passes to the <literal>EXCEPTION</literal> list.
     The list is searched for the first <replaceable>condition</replaceable>
     matching the error that occurred.  If a match is found, the
     corresponding <replaceable>handler_statements</replaceable> are
     executed, and then control passes to the next statement after
     <literal>END</literal>.  If no match is found, the error propagates out
     as though the <literal>EXCEPTION</literal> clause were not there at all:
     the error can be caught by an enclosing block with
     <literal>EXCEPTION</literal>, or if there is none it aborts processing
     of the function.
    </para>

    <para>
     The <replaceable>condition</replaceable> names can be any of
     those shown in <xref linkend="errcodes-appendix"/>.  A category
     name matches any error within its category.  The special
     condition name <literal>OTHERS</literal> matches every error type except
     <literal>QUERY_CANCELED</literal> and <literal>ASSERT_FAILURE</literal>.
     (It is possible, but often unwise, to trap those two error types
     by name.)  Condition names are
     not case-sensitive.  Also, an error condition can be specified
     by <literal>SQLSTATE</literal> code; for example these are equivalent:
<programlisting>
WHEN division_by_zero THEN ...
WHEN SQLSTATE '22012' THEN ...
</programlisting>
    </para>

    <para>
     If a new error occurs within the selected
     <replaceable>handler_statements</replaceable>, it cannot be caught
     by this <literal>EXCEPTION</literal> clause, but is propagated out.
     A surrounding <literal>EXCEPTION</literal> clause could catch it.
    </para>

    <para>
     When an error is caught by an <literal>EXCEPTION</literal> clause,
     the local variables of the <application>PL/pgSQL</application> function
     remain as they were when the error occurred, but all changes
     to persistent database state within the block are rolled back.
     As an example, consider this fragment:

<programlisting>
INSERT INTO mytab(firstname, lastname) VALUES('Tom', 'Jones');
BEGIN
    UPDATE mytab SET firstname = 'Joe' WHERE lastname = 'Jones';
    x := x + 1;
    y := x / 0;
EXCEPTION
    WHEN division_by_zero THEN
        RAISE NOTICE 'caught division_by_zero';
        RETURN x;
END;
</programlisting>

     When control reaches the assignment to <literal>y</literal>, it will
     fail with a <literal>division_by_zero</literal> error.  This will be caught by
     the <literal>EXCEPTION</literal>

Title: Exception Handling in PL/pgSQL
Summary
PL/pgSQL functions can trap errors using BEGIN blocks with EXCEPTION clauses. If an error occurs within the block's statements, processing is abandoned, and the EXCEPTION list is searched for a matching condition. If a match is found, the corresponding handler statements are executed. If no match is found, the error propagates outwards. Condition names can be error codes or SQLSTATE codes. Local variables retain their values when the error occurred, but database changes within the block are rolled back.