The trick consists in using the NOCOPY keyword to pass variables by reference and not by copy.
PROCEDURE PROC(x_out_param OUT NOCOPY VARCHAR2) IS BEGIN ... x_out_param := 'some value'; RAISE MY_ERROR_EXCEPTION; END PROC; PROCEDURE MAIN(x_out_param OUT VARCHAR2) IS BEGIN ... PROC(x_out_param); EXCEPTION WHEN MY_ERROR_EXCEPTION THEN RETURN 1; WHEN OTHERS THEN RETURN 2; END MAIN;