From 7ef8ec6f13906d6305db5142ba2415911e81852f Mon Sep 17 00:00:00 2001
From: Marti Raudsepp <marti@juffo.org>
Date: Tue, 9 Nov 2010 18:32:22 +0200
Subject: [PATCH 2/2] Add tests for current PL/Python exception behavior

---
 src/pl/plpython/expected/plpython_error.out |  100 +++++++++++++++++++++++++++
 src/pl/plpython/sql/plpython_error.sql      |   89 ++++++++++++++++++++++++
 2 files changed, 189 insertions(+), 0 deletions(-)

diff --git a/src/pl/plpython/expected/plpython_error.out b/src/pl/plpython/expected/plpython_error.out
index 1f24c13..18b7b99 100644
--- a/src/pl/plpython/expected/plpython_error.out
+++ b/src/pl/plpython/expected/plpython_error.out
@@ -121,3 +121,103 @@ SELECT valid_type('rick');
  
 (1 row)
 
+/* raise plpy.Error */
+CREATE FUNCTION raise_error() RETURNS void
+	AS
+'raise plpy.Error("Raising error")'
+	LANGUAGE plpythonu;
+SELECT raise_error();
+ERROR:  PL/Python: plpy.Error: Raising error
+CONTEXT:  PL/Python function "raise_error"
+/* Broken behavior: raise plpy.Fatal. This is still mapped to PostgreSQL ERROR
+ * log level.
+ */
+CREATE FUNCTION broken_raise_fatal() RETURNS void
+	AS
+'raise plpy.Fatal("Raising fatal")'
+	LANGUAGE plpythonu;
+SELECT broken_raise_fatal();
+ERROR:  PL/Python: plpy.Fatal: Raising fatal
+CONTEXT:  PL/Python function "broken_raise_fatal"
+/* raising plpy.Error can be caught and ignored
+ */
+CREATE FUNCTION catch_error() RETURNS text
+	AS
+'try:
+	raise plpy.Error("catch me if you can!")
+except:
+	plpy.notice("gotcha")
+	return "retval"
+'
+	LANGUAGE plpythonu;
+SELECT catch_error();
+NOTICE:  gotcha
+CONTEXT:  PL/Python function "catch_error"
+ catch_error 
+-------------
+ retval
+(1 row)
+
+/* catch plpy.Fatal by name
+ */
+CREATE FUNCTION catch_fatal() RETURNS text
+	AS
+'try:
+	raise plpy.Fatal("catch me if you can!")
+except plpy.Fatal:
+	return "retval"
+'
+	LANGUAGE plpythonu;
+SELECT catch_fatal();
+ catch_fatal 
+-------------
+ retval
+(1 row)
+
+/* Broken behavior: plpy.error can be caught and the exception handler is
+ * executed, but cannot be silenced
+ */
+CREATE FUNCTION broken_error_catch() RETURNS text
+	AS
+'try:
+	plpy.error("catch me if you can!")
+except:
+	plpy.notice("caught but cannot ignore")
+	return "retval"
+'
+	LANGUAGE plpythonu;
+SELECT broken_error_catch();
+NOTICE:  caught but cannot ignore
+CONTEXT:  PL/Python function "broken_error_catch"
+ERROR:  catch me if you can!
+CONTEXT:  PL/Python function "broken_error_catch"
+/* Broken behavior: plpy.error can be caught, but errors in the exception
+ * handler are ignored
+ */
+CREATE FUNCTION broken_catch_exceptions() RETURNS void
+	AS
+'try:
+	plpy.error("catch me if you can!")
+except:
+	plpy.notice("caught but cannot ignore")
+	this is totally, broken-code
+'
+	LANGUAGE plpythonu;
+SELECT broken_catch_exceptions();
+NOTICE:  caught but cannot ignore
+CONTEXT:  PL/Python function "broken_catch_exceptions"
+ERROR:  catch me if you can!
+CONTEXT:  PL/Python function "broken_catch_exceptions"
+/* plpy.error can be overridden with another message
+ */
+CREATE FUNCTION catch_error_override() RETURNS void
+	AS
+'try:
+	plpy.error("catch me if you can!")
+except:
+	plpy.error("replaced with a new error")
+'
+	LANGUAGE plpythonu;
+SELECT catch_error_override();
+ERROR:  replaced with a new error
+CONTEXT:  PL/Python function "catch_error_override"
diff --git a/src/pl/plpython/sql/plpython_error.sql b/src/pl/plpython/sql/plpython_error.sql
index 5ca6849..99891e3 100644
--- a/src/pl/plpython/sql/plpython_error.sql
+++ b/src/pl/plpython/sql/plpython_error.sql
@@ -107,3 +107,92 @@ return None
 	LANGUAGE plpythonu;
 
 SELECT valid_type('rick');
+
+/* raise plpy.Error */
+CREATE FUNCTION raise_error() RETURNS void
+	AS
+'raise plpy.Error("Raising error")'
+	LANGUAGE plpythonu;
+
+SELECT raise_error();
+
+/* Broken behavior: raise plpy.Fatal. This is still mapped to PostgreSQL ERROR
+ * log level.
+ */
+CREATE FUNCTION broken_raise_fatal() RETURNS void
+	AS
+'raise plpy.Fatal("Raising fatal")'
+	LANGUAGE plpythonu;
+
+SELECT broken_raise_fatal();
+
+/* raising plpy.Error can be caught and ignored
+ */
+CREATE FUNCTION catch_error() RETURNS text
+	AS
+'try:
+	raise plpy.Error("catch me if you can!")
+except:
+	plpy.notice("gotcha")
+	return "retval"
+'
+	LANGUAGE plpythonu;
+
+SELECT catch_error();
+
+/* catch plpy.Fatal by name
+ */
+CREATE FUNCTION catch_fatal() RETURNS text
+	AS
+'try:
+	raise plpy.Fatal("catch me if you can!")
+except plpy.Fatal:
+	return "retval"
+'
+	LANGUAGE plpythonu;
+
+SELECT catch_fatal();
+
+/* Broken behavior: plpy.error can be caught and the exception handler is
+ * executed, but cannot be silenced
+ */
+CREATE FUNCTION broken_error_catch() RETURNS text
+	AS
+'try:
+	plpy.error("catch me if you can!")
+except:
+	plpy.notice("caught but cannot ignore")
+	return "retval"
+'
+	LANGUAGE plpythonu;
+
+SELECT broken_error_catch();
+
+/* Broken behavior: plpy.error can be caught, but errors in the exception
+ * handler are ignored
+ */
+CREATE FUNCTION broken_catch_exceptions() RETURNS void
+	AS
+'try:
+	plpy.error("catch me if you can!")
+except:
+	plpy.notice("caught but cannot ignore")
+	this is totally, broken-code
+'
+	LANGUAGE plpythonu;
+
+SELECT broken_catch_exceptions();
+
+/* plpy.error can be overridden with another message
+ */
+CREATE FUNCTION catch_error_override() RETURNS void
+	AS
+'try:
+	plpy.error("catch me if you can!")
+except:
+	plpy.error("replaced with a new error")
+'
+	LANGUAGE plpythonu;
+
+SELECT catch_error_override();
+
-- 
1.7.3.2

