diff --git a/src/pl/plpython/expected/plpython_error.out b/src/pl/plpython/expected/plpython_error.out
index 06043289fed7be0a69bba9abef97f935608c4c50..8a0b08fe163d7e4fb81fe594a202fb75512f9d08 100644
--- a/src/pl/plpython/expected/plpython_error.out
+++ b/src/pl/plpython/expected/plpython_error.out
@@ -19,3 +19,20 @@ SELECT valid_type('rick');
  
 (1 row)
 
+--
+-- Test Unicode error handling.
+--
+SELECT unicode_return_error();
+ERROR:  plpython: function "unicode_return_error" could not create return value
+DETAIL:  exceptions.UnicodeEncodeError: 'ascii' codec can't encode character u'\x80' in position 0: ordinal not in range(128)
+INSERT INTO unicode_test (testvalue) VALUES ('test');
+ERROR:  plpython: function "unicode_trigger_error" could not modify tuple
+DETAIL:  exceptions.UnicodeEncodeError: 'ascii' codec can't encode character u'\x80' in position 0: ordinal not in range(128)
+SELECT unicode_plan_error1();
+WARNING:  plpython: in function unicode_plan_error1:
+DETAIL:  plpy.Error: Unknown error in PLy_spi_execute_plan
+ERROR:  plpython: function "unicode_plan_error1" could not execute plan
+DETAIL:  exceptions.UnicodeEncodeError: 'ascii' codec can't encode character u'\x80' in position 0: ordinal not in range(128)
+SELECT unicode_plan_error2();
+ERROR:  plpython: function "unicode_plan_error2" could not execute plan
+DETAIL:  exceptions.UnicodeEncodeError: 'ascii' codec can't encode character u'\x80' in position 0: ordinal not in range(128)
diff --git a/src/pl/plpython/expected/plpython_function.out b/src/pl/plpython/expected/plpython_function.out
index cc1415dca8d7402ffa68df4f9d1bd16a74d02caf..516d0576899bfa95d94a926c7121ee4b05293d61 100644
--- a/src/pl/plpython/expected/plpython_function.out
+++ b/src/pl/plpython/expected/plpython_function.out
@@ -267,3 +267,25 @@ LANGUAGE plpythonu;
 CREATE OR REPLACE FUNCTION newline_crlf() RETURNS integer AS
 'x = 100\r\ny = 23\r\nreturn x + y\r\n'
 LANGUAGE plpythonu;
+--
+-- Unicode error handling
+--
+CREATE FUNCTION unicode_return_error() RETURNS text AS '
+return u"\\x80"
+' LANGUAGE plpythonu;
+CREATE FUNCTION unicode_trigger_error() RETURNS trigger AS '
+TD["new"]["testvalue"] = u"\\x80"
+return "MODIFY"
+' LANGUAGE plpythonu;
+CREATE TRIGGER unicode_test_bi BEFORE INSERT ON unicode_test
+  FOR EACH ROW EXECUTE PROCEDURE unicode_trigger_error();
+CREATE FUNCTION unicode_plan_error1() RETURNS text AS '
+plan = plpy.prepare("SELECT $1 AS testvalue", ["text"])
+rv = plpy.execute(plan, [u"\\x80"], 1)
+return rv[0]["testvalue"]
+' LANGUAGE plpythonu;
+CREATE FUNCTION unicode_plan_error2() RETURNS text AS '
+plan = plpy.prepare("SELECT $1 AS testvalue1, $2 AS testvalue2", ["text", "text"])
+rv = plpy.execute(plan, u"\\x80", 1)
+return rv[0]["testvalue1"]
+' LANGUAGE plpythonu;
diff --git a/src/pl/plpython/expected/plpython_schema.out b/src/pl/plpython/expected/plpython_schema.out
index e94e7bbcf8818bc15a70c85da3a224b00d1c3cb9..727e4b83d92fa2fc2255a8c24dde91596e27af6b 100644
--- a/src/pl/plpython/expected/plpython_schema.out
+++ b/src/pl/plpython/expected/plpython_schema.out
@@ -41,3 +41,6 @@ CREATE TABLE xsequences (
 	sequence text not null
 	) ;
 CREATE INDEX xsequences_pid_idx ON xsequences(pid) ;
+CREATE TABLE unicode_test (
+	testvalue  text NOT NULL
+);
diff --git a/src/pl/plpython/plpython.c b/src/pl/plpython/plpython.c
index 3d7230ffca958ee0f8446e161378da85e79a79e7..b1d47c778205df118884c5870cd58afd411b57ac 100644
--- a/src/pl/plpython/plpython.c
+++ b/src/pl/plpython/plpython.c
@@ -29,7 +29,7 @@
  * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  *
  * IDENTIFICATION
- *	$PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.64 2005/07/05 18:15:51 momjian Exp $
+ *	$PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.65 2005/07/10 04:56:55 momjian Exp $
  *
  *********************************************************************
  */
@@ -517,6 +517,8 @@ PLy_modify_tuple(PLyProcedure * proc, PyObject * pltd, TriggerData *tdata,
 			if (plval != Py_None && !tupdesc->attrs[atti]->attisdropped)
 			{
 				plstr = PyObject_Str(plval);
+				if (!plstr)
+					PLy_elog(ERROR, "function \"%s\" could not modify tuple", proc->proname);
 				src = PyString_AsString(plstr);
 
 				modvalues[i] = FunctionCall3(&proc->result.out.r.atts[atti].typfunc,
@@ -774,6 +776,8 @@ PLy_function_handler(FunctionCallInfo fcinfo, PLyProcedure * proc)
 		{
 			fcinfo->isnull = false;
 			plrv_so = PyObject_Str(plrv);
+			if (!plrv_so)
+				PLy_elog(ERROR, "function \"%s\" could not create return value", proc->proname);
 			plrv_sc = PyString_AsString(plrv_so);
 			rv = FunctionCall3(&proc->result.out.d.typfunc,
 							   PointerGetDatum(plrv_sc),
@@ -2019,7 +2023,9 @@ PLy_spi_execute_plan(PyObject * ob, PyObject * list, long limit)
 		char	   *sv;
 
 		PyObject   *so = PyObject_Str(list);
-
+		if (!so)
+			PLy_elog(ERROR, "function \"%s\" could not execute plan",
+					 PLy_procedure_name(PLy_curr_procedure));
 		sv = PyString_AsString(so);
 		PLy_exception_set(PLy_exc_spi_error,
 						  "Expected sequence of %d arguments, got %d. %s",
@@ -2044,6 +2050,9 @@ PLy_spi_execute_plan(PyObject * ob, PyObject * list, long limit)
 			if (elem != Py_None)
 			{
 				so = PyObject_Str(elem);
+				if (!so)
+					PLy_elog(ERROR, "function \"%s\" could not execute plan",
+							 PLy_procedure_name(PLy_curr_procedure));
 				sv = PyString_AsString(so);
 
 				/*
@@ -2531,7 +2540,13 @@ PLy_traceback(int *xlevel)
 	else
 		vstr = "Unknown";
 
-	estr = PyString_AsString(eob);
+	/*
+	 * I'm not sure what to do if eob is NULL here -- we can't call
+	 * PLy_elog because that function calls us, so we could end up
+	 * with infinite recursion.  I'm not even sure if eob could be
+	 * NULL here -- would an Assert() be more appropriate?
+	 */
+	estr = eob ? PyString_AsString(eob) : "Unknown Exception";
 	xstr = PLy_printf("%s: %s", estr, vstr);
 
 	Py_DECREF(eob);
diff --git a/src/pl/plpython/sql/plpython_error.sql b/src/pl/plpython/sql/plpython_error.sql
index 2f0486fed9231ebd6da05900f8291c5be0d233b2..b04b23ef95ebcf76239af5412f5ebe44fc0db15a 100644
--- a/src/pl/plpython/sql/plpython_error.sql
+++ b/src/pl/plpython/sql/plpython_error.sql
@@ -7,3 +7,12 @@ SELECT invalid_type_uncaught('rick');
 SELECT invalid_type_caught('rick');
 SELECT invalid_type_reraised('rick');
 SELECT valid_type('rick');
+
+--
+-- Test Unicode error handling.
+--
+
+SELECT unicode_return_error();
+INSERT INTO unicode_test (testvalue) VALUES ('test');
+SELECT unicode_plan_error1();
+SELECT unicode_plan_error2();
diff --git a/src/pl/plpython/sql/plpython_function.sql b/src/pl/plpython/sql/plpython_function.sql
index 25ac388495a97689651cc4aebe7b522ac6ca587e..e3ec2afe01481e4cd4e396aed895bc0e3459fb4c 100644
--- a/src/pl/plpython/sql/plpython_function.sql
+++ b/src/pl/plpython/sql/plpython_function.sql
@@ -313,3 +313,31 @@ LANGUAGE plpythonu;
 CREATE OR REPLACE FUNCTION newline_crlf() RETURNS integer AS
 'x = 100\r\ny = 23\r\nreturn x + y\r\n'
 LANGUAGE plpythonu;
+
+--
+-- Unicode error handling
+--
+
+CREATE FUNCTION unicode_return_error() RETURNS text AS '
+return u"\\x80"
+' LANGUAGE plpythonu;
+
+CREATE FUNCTION unicode_trigger_error() RETURNS trigger AS '
+TD["new"]["testvalue"] = u"\\x80"
+return "MODIFY"
+' LANGUAGE plpythonu;
+
+CREATE TRIGGER unicode_test_bi BEFORE INSERT ON unicode_test
+  FOR EACH ROW EXECUTE PROCEDURE unicode_trigger_error();
+
+CREATE FUNCTION unicode_plan_error1() RETURNS text AS '
+plan = plpy.prepare("SELECT $1 AS testvalue", ["text"])
+rv = plpy.execute(plan, [u"\\x80"], 1)
+return rv[0]["testvalue"]
+' LANGUAGE plpythonu;
+
+CREATE FUNCTION unicode_plan_error2() RETURNS text AS '
+plan = plpy.prepare("SELECT $1 AS testvalue1, $2 AS testvalue2", ["text", "text"])
+rv = plpy.execute(plan, u"\\x80", 1)
+return rv[0]["testvalue1"]
+' LANGUAGE plpythonu;
diff --git a/src/pl/plpython/sql/plpython_schema.sql b/src/pl/plpython/sql/plpython_schema.sql
index 2f8766431fae803ff9c2b0a8ea491f75b832cb8c..1f5ee6eaea6e88e14af4faf04f5165f90723bac9 100644
--- a/src/pl/plpython/sql/plpython_schema.sql
+++ b/src/pl/plpython/sql/plpython_schema.sql
@@ -39,4 +39,6 @@ CREATE TABLE xsequences (
 	) ;
 CREATE INDEX xsequences_pid_idx ON xsequences(pid) ;
 
-
+CREATE TABLE unicode_test (
+	testvalue  text NOT NULL
+);