SELECT * FROM test_type_record_error1();
 ERROR:  key "second" not found in mapping
 HINT:  To return null in a column, add the value None to the mapping with the key named after the column.
-CONTEXT:  PL/Python function "test_type_record_error1"
+CONTEXT:  while creating return value
+PL/Python function "test_type_record_error1"
 CREATE FUNCTION test_type_record_error2() RETURNS type_record AS $$
     return [ 'first' ]
 $$ LANGUAGE plpythonu;
 SELECT * FROM test_type_record_error2();
 ERROR:  length of returned sequence did not match number of columns in row
-CONTEXT:  PL/Python function "test_type_record_error2"
+CONTEXT:  while creating return value
+PL/Python function "test_type_record_error2"
 CREATE FUNCTION test_type_record_error3() RETURNS type_record AS $$
     class type_record: pass
     type_record.first = 'first'
 SELECT * FROM test_type_record_error3();
 ERROR:  attribute "second" does not exist in Python object
 HINT:  To return null in a column, let the returned object have an attribute named after column with value None.
-CONTEXT:  PL/Python function "test_type_record_error3"
+CONTEXT:  while creating return value
+PL/Python function "test_type_record_error3"
 
 FOR EACH ROW EXECUTE PROCEDURE stupid4();
 UPDATE trigger_test SET v = 'null' WHERE i = 0;
 ERROR:  TD["new"] deleted, cannot modify row
-CONTEXT:  PL/Python function "stupid4"
+CONTEXT:  while modifying trigger row
+PL/Python function "stupid4"
 DROP TRIGGER stupid_trigger4 ON trigger_test;
 -- TD not a dictionary
 CREATE FUNCTION stupid5() RETURNS trigger
 FOR EACH ROW EXECUTE PROCEDURE stupid5();
 UPDATE trigger_test SET v = 'null' WHERE i = 0;
 ERROR:  TD["new"] is not a dictionary
-CONTEXT:  PL/Python function "stupid5"
+CONTEXT:  while modifying trigger row
+PL/Python function "stupid5"
 DROP TRIGGER stupid_trigger5 ON trigger_test;
 -- TD not having string keys
 CREATE FUNCTION stupid6() RETURNS trigger
 FOR EACH ROW EXECUTE PROCEDURE stupid6();
 UPDATE trigger_test SET v = 'null' WHERE i = 0;
 ERROR:  TD["new"] dictionary key at ordinal position 0 is not a string
-CONTEXT:  PL/Python function "stupid6"
+CONTEXT:  while modifying trigger row
+PL/Python function "stupid6"
 DROP TRIGGER stupid_trigger6 ON trigger_test;
 -- TD keys not corresponding to row columns
 CREATE FUNCTION stupid7() RETURNS trigger
 FOR EACH ROW EXECUTE PROCEDURE stupid7();
 UPDATE trigger_test SET v = 'null' WHERE i = 0;
 ERROR:  key "a" found in TD["new"] does not exist as a column in the triggering row
-CONTEXT:  PL/Python function "stupid7"
+CONTEXT:  while modifying trigger row
+PL/Python function "stupid7"
 DROP TRIGGER stupid_trigger7 ON trigger_test;
 -- calling a trigger function directly
 SELECT stupid7();
 
 INFO:  (100, <type 'int'>)
 CONTEXT:  PL/Python function "test_type_conversion_uint2"
 ERROR:  value for domain uint2 violates check constraint "uint2_check"
-CONTEXT:  PL/Python function "test_type_conversion_uint2"
+CONTEXT:  while creating return value
+PL/Python function "test_type_conversion_uint2"
 SELECT * FROM test_type_conversion_uint2(null, 1);
 INFO:  (None, <type 'NoneType'>)
 CONTEXT:  PL/Python function "test_type_conversion_uint2"
 INFO:  ('\\x68656c6c6f20776f7264', <type 'str'>)
 CONTEXT:  PL/Python function "test_type_conversion_bytea10"
 ERROR:  value for domain bytea10 violates check constraint "bytea10_check"
-CONTEXT:  PL/Python function "test_type_conversion_bytea10"
+CONTEXT:  while creating return value
+PL/Python function "test_type_conversion_bytea10"
 SELECT * FROM test_type_conversion_bytea10(null, 'hello word');
 ERROR:  value for domain bytea10 violates check constraint "bytea10_check"
 SELECT * FROM test_type_conversion_bytea10('hello word', null);
 INFO:  ('\\x68656c6c6f20776f7264', <type 'str'>)
 CONTEXT:  PL/Python function "test_type_conversion_bytea10"
 ERROR:  value for domain bytea10 violates check constraint "bytea10_check"
-CONTEXT:  PL/Python function "test_type_conversion_bytea10"
+CONTEXT:  while creating return value
+PL/Python function "test_type_conversion_bytea10"
 
 return rv[0]["testvalue1"]
 ' LANGUAGE plpythonu;
 SELECT unicode_return_error();
-ERROR:  PL/Python: could not create string representation of Python object, while creating return value
+ERROR:  PL/Python: could not create string representation of Python object
 DETAIL:  <type 'exceptions.UnicodeEncodeError'>: 'ascii' codec can't encode character u'\x80' in position 0: ordinal not in range(128)
-CONTEXT:  PL/Python function "unicode_return_error"
+CONTEXT:  while creating return value
+PL/Python function "unicode_return_error"
 INSERT INTO unicode_test (testvalue) VALUES ('test');
-ERROR:  PL/Python: could not compute string representation of Python object, while modifying trigger row
+ERROR:  PL/Python: could not create string representation of Python object
 DETAIL:  <type 'exceptions.UnicodeEncodeError'>: 'ascii' codec can't encode character u'\x80' in position 0: ordinal not in range(128)
-CONTEXT:  PL/Python function "unicode_trigger_error"
+CONTEXT:  while modifying trigger row
+PL/Python function "unicode_trigger_error"
 SELECT unicode_plan_error1();
 WARNING:  PL/Python: <class 'plpy.Error'>: unrecognized error in PLy_spi_execute_plan
 CONTEXT:  PL/Python function "unicode_plan_error1"
 
 return rv[0]["testvalue1"]
 ' LANGUAGE plpythonu;
 SELECT unicode_return_error();
-ERROR:  PL/Python: could not create string representation of Python object, while creating return value
+ERROR:  PL/Python: could not create string representation of Python object
 DETAIL:  exceptions.UnicodeError: ASCII encoding error: ordinal not in range(128)
-CONTEXT:  PL/Python function "unicode_return_error"
+CONTEXT:  while creating return value
+PL/Python function "unicode_return_error"
 INSERT INTO unicode_test (testvalue) VALUES ('test');
-ERROR:  PL/Python: could not compute string representation of Python object, while modifying trigger row
+ERROR:  PL/Python: could not create string representation of Python object
 DETAIL:  exceptions.UnicodeError: ASCII encoding error: ordinal not in range(128)
-CONTEXT:  PL/Python function "unicode_trigger_error"
+CONTEXT:  while modifying trigger row
+PL/Python function "unicode_trigger_error"
 SELECT unicode_plan_error1();
 WARNING:  PL/Python: plpy.Error: unrecognized error in PLy_spi_execute_plan
 CONTEXT:  PL/Python function "unicode_plan_error1"
 
 return rv[0]["testvalue1"]
 ' LANGUAGE plpythonu;
 SELECT unicode_return_error();
-ERROR:  PL/Python: could not create string representation of Python object, while creating return value
+ERROR:  PL/Python: could not create string representation of Python object
 DETAIL:  exceptions.UnicodeEncodeError: 'ascii' codec can't encode character u'\x80' in position 0: ordinal not in range(128)
-CONTEXT:  PL/Python function "unicode_return_error"
+CONTEXT:  while creating return value
+PL/Python function "unicode_return_error"
 INSERT INTO unicode_test (testvalue) VALUES ('test');
-ERROR:  PL/Python: could not compute string representation of Python object, while modifying trigger row
+ERROR:  PL/Python: could not create string representation of Python object
 DETAIL:  exceptions.UnicodeEncodeError: 'ascii' codec can't encode character u'\x80' in position 0: ordinal not in range(128)
-CONTEXT:  PL/Python function "unicode_trigger_error"
+CONTEXT:  while modifying trigger row
+PL/Python function "unicode_trigger_error"
 SELECT unicode_plan_error1();
 WARNING:  PL/Python: plpy.Error: unrecognized error in PLy_spi_execute_plan
 CONTEXT:  PL/Python function "unicode_plan_error1"
 
 
 SELECT test_void_func2(); -- should fail
 ERROR:  PL/Python function with return type "void" did not return None
-CONTEXT:  PL/Python function "test_void_func2"
+CONTEXT:  while creating return value
+PL/Python function "test_void_func2"
 SELECT test_return_none(), test_return_none() IS NULL AS "is null";
  test_return_none | is null 
 ------------------+---------
 
                errcontext("PL/Python function \"%s\"", PLy_procedure_name(PLy_curr_procedure));
 }
 
+static void
+plpython_trigger_error_callback(void *arg)
+{
+       if (PLy_curr_procedure)
+               errcontext("while modifying trigger row");
+}
+
+static void
+plpython_return_error_callback(void *arg)
+{
+       if (PLy_curr_procedure)
+               errcontext("while creating return value");
+}
+
 Datum
 plpython_call_handler(PG_FUNCTION_ARGS)
 {
        Datum      *volatile modvalues;
        char       *volatile modnulls;
        TupleDesc       tupdesc;
+       ErrorContextCallback plerrcontext;
+
+       plerrcontext.callback = plpython_trigger_error_callback;
+       plerrcontext.previous = error_context_stack;
+       error_context_stack = &plerrcontext;
 
        plntup = plkeys = platt = plval = plstr = NULL;
        modattrs = NULL;
                        {
                                plstr = PyObject_Str(plval);
                                if (!plstr)
-                                       PLy_elog(ERROR, "could not compute string representation of Python object, while modifying trigger row");
+                                       PLy_elog(ERROR, "could not create string representation of Python object");
                                src = PyString_AsString(plstr);
 
                                modvalues[i] =
        pfree(modvalues);
        pfree(modnulls);
 
+       error_context_stack = plerrcontext.previous;
+
        return rtup;
 }
 
        PyObject   *volatile plrv = NULL;
        PyObject   *volatile plrv_so = NULL;
        char       *plrv_sc;
+       ErrorContextCallback plerrcontext;
 
        PG_TRY();
        {
                        }
                }
 
+               plerrcontext.callback = plpython_return_error_callback;
+               plerrcontext.previous = error_context_stack;
+               error_context_stack = &plerrcontext;
+
                /*
                 * If the function is declared to return void, the Python return value
                 * must be None. For void-returning functions, we also treat a None
                        fcinfo->isnull = false;
                        plrv_so = PyObject_Str(plrv);
                        if (!plrv_so)
-                               PLy_elog(ERROR, "could not create string representation of Python object, while creating return value");
+                               PLy_elog(ERROR, "could not create string representation of Python object");
                        plrv_sc = PyString_AsString(plrv_so);
                        rv = InputFunctionCall(&proc->result.out.d.typfunc,
                                                                   plrv_sc,
        }
        PG_END_TRY();
 
+       error_context_stack = plerrcontext.previous;
+
        Py_XDECREF(plargs);
        Py_DECREF(plrv);
        Py_XDECREF(plrv_so);