RoutineRaiseException
Exception thrown when a PL/pgSQL routine raises an error of its own, through RAISE EXCEPTION.
This is the database saying no on purpose: a business rule expressed where the data is, rather than a routine that turned out to be broken. Those are RoutineAssertionException and are a separate type precisely so the two can be handled apart.
There is no reason enum here because there is nothing to tell apart. A plain RAISE EXCEPTION reports P0001; P0000 is reachable only by asking for it - RAISE ... USING ERRCODE = 'plpgsql_error' - so it is another deliberate raise rather than an unclassified failure. Which one it was is sqlState, and what it was about is dbMessage.
RAISE EXCEPTION ... USING ERRCODE reaching further than P0, on the other hand, leaves this class entirely: ERRCODE = '23505' is routed by the code it names and arrives as a ConstraintViolationException.
Parameters
The SQL state code returned by the database.
The original error message from the database server.