Index: app/pdb/plug-in-cmds.c
===================================================================
--- app/pdb/plug-in-cmds.c	(revision 26527)
+++ app/pdb/plug-in-cmds.c	(working copy)
@@ -273,6 +273,58 @@ plugin_icon_register_invoker (GimpProced
   return gimp_procedure_get_return_values (procedure, success);
 }
 
+static GValueArray *
+plugin_set_error_handler_invoker (GimpProcedure      *procedure,
+                                  Gimp               *gimp,
+                                  GimpContext        *context,
+                                  GimpProgress       *progress,
+                                  const GValueArray  *args,
+                                  GError            **error)
+{
+  gboolean success = TRUE;
+  gint32 handler;
+
+  handler = g_value_get_enum (&args->values[0]);
+
+  if (success)
+    {
+      GimpPlugIn *plug_in = gimp->plug_in_manager->current_plug_in;
+
+      if (plug_in)
+        {
+          gimp_plug_in_set_error_handler (plug_in, handler);
+        }
+      else
+        {
+          success = FALSE;
+        }
+    }
+
+  return gimp_procedure_get_return_values (procedure, success);
+}
+
+static GValueArray *
+plugin_get_procedure_error_invoker (GimpProcedure      *procedure,
+                                    Gimp               *gimp,
+                                    GimpContext        *context,
+                                    GimpProgress       *progress,
+                                    const GValueArray  *args,
+                                    GError            **error)
+{
+  GValueArray *return_vals;
+  gchar *msg = NULL;
+
+  GimpPlugIn          *plug_in    = gimp->plug_in_manager->current_plug_in;
+  GimpPlugInProcFrame *proc_frame = gimp_plug_in_get_proc_frame (plug_in);
+
+  msg = g_strdup (gimp_plug_in_proc_frame_get_error (proc_frame));
+
+  return_vals = gimp_procedure_get_return_values (procedure, TRUE);
+  g_value_take_string (&return_vals->values[1], msg);
+
+  return return_vals;
+}
+
 void
 register_plug_in_procs (GimpPDB *pdb)
 {
@@ -533,4 +585,52 @@ register_plug_in_procs (GimpPDB *pdb)
                                                            GIMP_PARAM_READWRITE));
   gimp_pdb_register_procedure (pdb, procedure);
   g_object_unref (procedure);
+
+  /*
+   * gimp-plugin-set-error-handler
+   */
+  procedure = gimp_procedure_new (plugin_set_error_handler_invoker);
+  gimp_object_set_static_name (GIMP_OBJECT (procedure),
+                               "gimp-plugin-set-error-handler");
+  gimp_procedure_set_static_strings (procedure,
+                                     "gimp-plugin-set-error-handler",
+                                     "Sets an error handler for procedure calls.",
+                                     "This procedure changes the way that errors in procedure calls are handled.",
+                                     "Sven Neumann <sven@gimp.org>",
+                                     "Sven Neumann",
+                                     "2008",
+                                     NULL);
+  gimp_procedure_add_argument (procedure,
+                               g_param_spec_enum ("handler",
+                                                  "handler",
+                                                  "Who's responsible for handling procedure call errors",
+                                                  GIMP_TYPE_PDB_ERROR_HANDLER,
+                                                  GIMP_PDB_ERROR_HANDLER_INTERNAL,
+                                                  GIMP_PARAM_READWRITE));
+  gimp_pdb_register_procedure (pdb, procedure);
+  g_object_unref (procedure);
+
+  /*
+   * gimp-plugin-get-procedure-error
+   */
+  procedure = gimp_procedure_new (plugin_get_procedure_error_invoker);
+  gimp_object_set_static_name (GIMP_OBJECT (procedure),
+                               "gimp-plugin-get-procedure-error");
+  gimp_procedure_set_static_strings (procedure,
+                                     "gimp-plugin-get-procedure-error",
+                                     "Retrieves the error message from the last procedure call.",
+                                     "This procedure is used in conjunction with 'gimp-plugin-set-error-handler'. A plug-in that has set the error handler to %GIMP_PDB_ERROR_HANDLER_PLUGIN can use this procedure to retrieve the error message from the last failed procedure call.",
+                                     "Sven Neumann <sven@gimp.org>",
+                                     "Sven Neumann",
+                                     "2008",
+                                     NULL);
+  gimp_procedure_add_return_value (procedure,
+                                   gimp_param_spec_string ("msg",
+                                                           "msg",
+                                                           "The error message from the last procedure call",
+                                                           FALSE, FALSE, FALSE,
+                                                           NULL,
+                                                           GIMP_PARAM_READWRITE));
+  gimp_pdb_register_procedure (pdb, procedure);
+  g_object_unref (procedure);
 }
Index: app/pdb/internal-procs.c
===================================================================
--- app/pdb/internal-procs.c	(revision 26527)
+++ app/pdb/internal-procs.c	(working copy)
@@ -29,7 +29,7 @@
 #include "internal-procs.h"
 
 
-/* 589 procedures registered total */
+/* 591 procedures registered total */
 
 void
 internal_procs_init (GimpPDB *pdb)
Index: app/plug-in/gimppluginprocframe.c
===================================================================
--- app/plug-in/gimppluginprocframe.c	(revision 26527)
+++ app/plug-in/gimppluginprocframe.c	(working copy)
@@ -77,6 +77,7 @@ gimp_plug_in_proc_frame_init (GimpPlugIn
   proc_frame->progress           = progress ? g_object_ref (progress) : NULL;
   proc_frame->progress_created   = FALSE;
   proc_frame->progress_cancel_id = 0;
+  proc_frame->pdb_error_message  = NULL;
 
   if (progress)
     gimp_plug_in_progress_attach (progress);
@@ -89,6 +90,12 @@ gimp_plug_in_proc_frame_dispose (GimpPlu
   g_return_if_fail (proc_frame != NULL);
   g_return_if_fail (GIMP_IS_PLUG_IN (plug_in));
 
+  if (proc_frame->pdb_error_message)
+    {
+      g_free (proc_frame->pdb_error_message);
+      proc_frame->pdb_error_message = NULL;
+    }
+
   if (proc_frame->progress)
     {
       gimp_plug_in_progress_end (plug_in, proc_frame);
@@ -198,3 +205,23 @@ gimp_plug_in_proc_frame_get_return_vals 
 
   return return_vals;
 }
+
+const gchar *
+gimp_plug_in_proc_frame_get_error (GimpPlugInProcFrame *proc_frame)
+{
+  g_return_val_if_fail (proc_frame != NULL, NULL);
+
+  return proc_frame->pdb_error_message;
+}
+
+void
+gimp_plug_in_proc_frame_set_error (GimpPlugInProcFrame *proc_frame,
+                                   const gchar         *error)
+{
+  g_return_if_fail (proc_frame != NULL);
+
+  if (proc_frame->pdb_error_message)
+    g_free (proc_frame->pdb_error_message);
+
+  proc_frame->pdb_error_message = g_strdup (error);
+}
Index: app/plug-in/gimpplugin.c
===================================================================
--- app/plug-in/gimpplugin.c	(revision 26527)
+++ app/plug-in/gimpplugin.c	(working copy)
@@ -162,6 +162,8 @@ gimp_plug_in_init (GimpPlugIn *plug_in)
 
   plug_in->temp_proc_frames   = NULL;
 
+  plug_in->error_handler      = GIMP_PDB_ERROR_HANDLER_INTERNAL;
+
   plug_in->plug_in_def        = NULL;
 }
 
@@ -939,6 +941,15 @@ gimp_plug_in_menu_register (GimpPlugIn  
 }
 
 void
+gimp_plug_in_set_error_handler (GimpPlugIn          *plug_in,
+                                GimpPDBErrorHandler  handler)
+{
+  g_return_if_fail (GIMP_IS_PLUG_IN (plug_in));
+
+  plug_in->error_handler = handler;
+}
+
+void
 gimp_plug_in_add_temp_proc (GimpPlugIn             *plug_in,
                             GimpTemporaryProcedure *proc)
 {
Index: app/plug-in/gimppluginprocframe.h
===================================================================
--- app/plug-in/gimppluginprocframe.h	(revision 26527)
+++ app/plug-in/gimppluginprocframe.h	(working copy)
@@ -34,10 +34,14 @@ struct _GimpPlugInProcFrame
 
   GValueArray   *return_vals;
 
+  /*  progress handling  */
   GimpProgress  *progress;
   gboolean       progress_created;
   gulong         progress_cancel_id;
 
+  /*  error handling  */
+  gchar         *pdb_error_message;
+
   /*  lists of things to clean up on dispose  */
   GList         *image_cleanups;
   GList         *item_cleanups;
@@ -61,5 +65,9 @@ void                  gimp_plug_in_proc_
 
 GValueArray * gimp_plug_in_proc_frame_get_return_vals (GimpPlugInProcFrame *proc_frame);
 
+const gchar * gimp_plug_in_proc_frame_get_error       (GimpPlugInProcFrame *proc_frame);
+void          gimp_plug_in_proc_frame_set_error       (GimpPlugInProcFrame *proc_frame,
+                                                       const gchar         *error);
+
 
 #endif /* __GIMP_PLUG_IN_PROC_FRAME_H__ */
Index: app/plug-in/gimpplugin.h
===================================================================
--- app/plug-in/gimpplugin.h	(revision 26527)
+++ app/plug-in/gimpplugin.h	(working copy)
@@ -68,6 +68,8 @@ struct _GimpPlugIn
 
   GList               *temp_proc_frames;
 
+  GimpPDBErrorHandler  error_handler;
+
   GimpPlugInDef       *plug_in_def;     /*  Valid during query() and init()   */
 };
 
@@ -92,28 +94,30 @@ void          gimp_plug_in_close        
                                              gboolean                kill_it);
 
 GimpPlugInProcFrame *
-              gimp_plug_in_get_proc_frame   (GimpPlugIn             *plug_in);
+              gimp_plug_in_get_proc_frame    (GimpPlugIn             *plug_in);
 
 GimpPlugInProcFrame *
-              gimp_plug_in_proc_frame_push  (GimpPlugIn             *plug_in,
-                                             GimpContext            *context,
-                                             GimpProgress           *progress,
-                                             GimpTemporaryProcedure *procedure);
-void          gimp_plug_in_proc_frame_pop   (GimpPlugIn             *plug_in);
-
-void          gimp_plug_in_main_loop        (GimpPlugIn             *plug_in);
-void          gimp_plug_in_main_loop_quit   (GimpPlugIn             *plug_in);
-
-const gchar * gimp_plug_in_get_undo_desc    (GimpPlugIn             *plug_in);
-
-gboolean      gimp_plug_in_menu_register    (GimpPlugIn             *plug_in,
-                                             const gchar            *proc_name,
-                                             const gchar            *menu_path);
-
-void          gimp_plug_in_add_temp_proc    (GimpPlugIn             *plug_in,
-                                             GimpTemporaryProcedure *procedure);
-void          gimp_plug_in_remove_temp_proc (GimpPlugIn             *plug_in,
-                                             GimpTemporaryProcedure *procedure);
-
+              gimp_plug_in_proc_frame_push   (GimpPlugIn             *plug_in,
+                                              GimpContext            *context,
+                                              GimpProgress           *progress,
+                                              GimpTemporaryProcedure *procedure);
+void          gimp_plug_in_proc_frame_pop    (GimpPlugIn             *plug_in);
+
+void          gimp_plug_in_main_loop         (GimpPlugIn             *plug_in);
+void          gimp_plug_in_main_loop_quit    (GimpPlugIn             *plug_in);
+
+const gchar * gimp_plug_in_get_undo_desc     (GimpPlugIn             *plug_in);
+
+gboolean      gimp_plug_in_menu_register     (GimpPlugIn             *plug_in,
+                                              const gchar            *proc_name,
+                                              const gchar            *menu_path);
+
+void          gimp_plug_in_set_error_handler (GimpPlugIn             *plug_in,
+                                              GimpPDBErrorHandler     handler);
+
+void          gimp_plug_in_add_temp_proc     (GimpPlugIn             *plug_in,
+                                              GimpTemporaryProcedure *procedure);
+void          gimp_plug_in_remove_temp_proc  (GimpPlugIn             *plug_in,
+                                              GimpTemporaryProcedure *procedure);
 
 #endif /* __GIMP_PLUG_IN_H__ */
Index: app/plug-in/gimpplugin-message.c
===================================================================
--- app/plug-in/gimpplugin-message.c	(revision 26527)
+++ app/plug-in/gimpplugin-message.c	(working copy)
@@ -406,6 +406,28 @@ gimp_plug_in_handle_tile_get (GimpPlugIn
 }
 
 static void
+gimp_plug_in_handle_proc_error (GimpPlugIn          *plug_in,
+                                GimpPlugInProcFrame *proc_frame,
+                                const gchar         *proc_name,
+                                GError              *error)
+{
+  switch (plug_in->error_handler)
+    {
+    case GIMP_PDB_ERROR_HANDLER_INTERNAL:
+      gimp_message (plug_in->manager->gimp, G_OBJECT (proc_frame->progress),
+                    GIMP_MESSAGE_ERROR,
+                    _("PDB calling error for procedure '%s':\n"
+                      "%s"),
+                    proc_name, error->message);
+      break;
+
+    case GIMP_PDB_ERROR_HANDLER_PLUGIN:
+      gimp_plug_in_proc_frame_set_error (proc_frame, error->message);
+      break;
+    }
+}
+
+static void
 gimp_plug_in_handle_proc_run (GimpPlugIn *plug_in,
                               GPProcRun  *proc_run)
 {
@@ -502,11 +524,7 @@ gimp_plug_in_handle_proc_run (GimpPlugIn
 
   if (error)
     {
-      gimp_message (plug_in->manager->gimp, G_OBJECT (proc_frame->progress),
-                    GIMP_MESSAGE_ERROR,
-                    _("PDB calling error for procedure '%s':\n"
-                      "%s"),
-                    canonical, error->message);
+      gimp_plug_in_handle_proc_error (plug_in, proc_frame, canonical, error);
       g_error_free (error);
     }
 
Index: libgimp/gimpenums.c.tail
===================================================================
--- libgimp/gimpenums.c.tail	(revision 26527)
+++ libgimp/gimpenums.c.tail	(working copy)
@@ -36,6 +36,7 @@ static const GimpGetTypeFunc get_type_fu
   gimp_offset_type_get_type,
   gimp_orientation_type_get_type,
   gimp_pdb_arg_type_get_type,
+  gimp_pdb_error_handler_get_type,
   gimp_pdb_proc_type_get_type,
   gimp_pdb_status_type_get_type,
   gimp_paint_application_mode_get_type,
@@ -90,6 +91,7 @@ static const gchar * const type_names[] 
   "GimpOffsetType",
   "GimpOrientationType",
   "GimpPDBArgType",
+  "GimpPDBErrorHandler",
   "GimpPDBProcType",
   "GimpPDBStatusType",
   "GimpPaintApplicationMode",
Index: tools/pdbgen/enums.pl
===================================================================
--- tools/pdbgen/enums.pl	(revision 26527)
+++ tools/pdbgen/enums.pl	(working copy)
@@ -294,6 +294,14 @@ package Gimp::CodeGen::enums;
 		       GIMP_PDB_PATH => 'GIMP_PDB_VECTORS',
 		       GIMP_PDB_BOUNDARY => 'GIMP_PDB_COLORARRAY' }
 	},
+    GimpPDBErrorHandler =>
+	{ contig => 1,
+	  header => 'libgimpbase/gimpbaseenums.h',
+	  symbols => [ qw(GIMP_PDB_ERROR_HANDLER_INTERNAL
+			  GIMP_PDB_ERROR_HANDLER_PLUGIN) ],
+	  mapping => { GIMP_PDB_ERROR_HANDLER_INTERNAL => '0',
+		       GIMP_PDB_ERROR_HANDLER_PLUGIN => '1' }
+	},
     GimpPDBProcType =>
 	{ contig => 1,
 	  header => 'libgimpbase/gimpbaseenums.h',
Index: tools/pdbgen/pdb/plug_in.pdb
===================================================================
--- tools/pdbgen/pdb/plug_in.pdb	(revision 26527)
+++ tools/pdbgen/pdb/plug_in.pdb	(working copy)
@@ -278,6 +278,66 @@ CODE
     );
 }
 
+sub plugin_set_error_handler {
+    $blurb = "Sets an error handler for procedure calls.";
+
+    $help = <<HELP;
+This procedure changes the way that errors in procedure calls are handled.
+HELP
+
+    &neo_pdb_misc('2008', '2.6');
+
+    @inargs = (
+	{ name => 'handler', type => 'enum GimpPDBErrorHandler',
+	  desc => "Who's responsible for handling procedure call errors" }
+    );
+
+    %invoke = (
+        code => <<'CODE'
+{
+  GimpPlugIn *plug_in = gimp->plug_in_manager->current_plug_in;
+
+  if (plug_in)
+    {
+      gimp_plug_in_set_error_handler (plug_in, handler);
+    }
+  else
+    {
+      success = FALSE;
+    }
+}
+CODE
+    );
+}
+
+sub plugin_get_procedure_error {
+    $blurb = 'Retrieves the error message from the last procedure call.';
+
+    $help = <<'HELP';
+This procedure is used in conjunction with gimp_plugin_set_error_handler().
+A plug-in that has set the error handler to %GIMP_PDB_ERROR_HANDLER_PLUGIN
+can use this procedure to retrieve the error message from the last failed
+procedure call.
+HELP
+
+    &neo_pdb_misc('2008', '2.6');
+
+    @outargs = (
+	{ name => 'msg', type => 'string',
+	  desc => 'The error message from the last procedure call' }
+    );
+
+    %invoke = (
+	code => <<'CODE'
+{
+  GimpPlugIn          *plug_in    = gimp->plug_in_manager->current_plug_in;
+  GimpPlugInProcFrame *proc_frame = gimp_plug_in_get_proc_frame (plug_in);
+
+  msg = g_strdup (gimp_plug_in_proc_frame_get_error (proc_frame));
+}
+CODE
+    );
+}
 
 @headers = qw(<string.h>
               <stdlib.h>
@@ -295,7 +355,9 @@ CODE
             plugin_help_register
             plugin_menu_register
             plugin_menu_branch_register
-            plugin_icon_register);
+            plugin_icon_register
+            plugin_set_error_handler
+            plugin_get_procedure_error);
 
 %exports = (app => [@procs], lib => [@procs[1,2,3,4,5]]);
 
Index: libgimpbase/gimpbaseenums.c
===================================================================
--- libgimpbase/gimpbaseenums.c	(revision 26527)
+++ libgimpbase/gimpbaseenums.c	(working copy)
@@ -864,6 +864,35 @@ gimp_pdb_arg_type_get_type (void)
 }
 
 GType
+gimp_pdb_error_handler_get_type (void)
+{
+  static const GEnumValue values[] =
+  {
+    { GIMP_PDB_ERROR_HANDLER_INTERNAL, "GIMP_PDB_ERROR_HANDLER_INTERNAL", "internal" },
+    { GIMP_PDB_ERROR_HANDLER_PLUGIN, "GIMP_PDB_ERROR_HANDLER_PLUGIN", "plugin" },
+    { 0, NULL, NULL }
+  };
+
+  static const GimpEnumDesc descs[] =
+  {
+    { GIMP_PDB_ERROR_HANDLER_INTERNAL, "GIMP_PDB_ERROR_HANDLER_INTERNAL", NULL },
+    { GIMP_PDB_ERROR_HANDLER_PLUGIN, "GIMP_PDB_ERROR_HANDLER_PLUGIN", NULL },
+    { 0, NULL, NULL }
+  };
+
+  static GType type = 0;
+
+  if (! type)
+    {
+      type = g_enum_register_static ("GimpPDBErrorHandler", values);
+      gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp");
+      gimp_enum_set_value_descriptions (type, descs);
+    }
+
+  return type;
+}
+
+GType
 gimp_pdb_proc_type_get_type (void)
 {
   static const GEnumValue values[] =
Index: libgimpbase/gimpbaseenums.h
===================================================================
--- libgimpbase/gimpbaseenums.h	(revision 26527)
+++ libgimpbase/gimpbaseenums.h	(working copy)
@@ -385,6 +385,17 @@ typedef enum
 } GimpPDBArgType;
 
 
+#define GIMP_TYPE_PDB_ERROR_HANDLER (gimp_pdb_error_handler_get_type ())
+
+GType gimp_pdb_error_handler_get_type (void) G_GNUC_CONST;
+
+typedef enum
+{
+  GIMP_PDB_ERROR_HANDLER_INTERNAL,
+  GIMP_PDB_ERROR_HANDLER_PLUGIN
+} GimpPDBErrorHandler;
+
+
 #define GIMP_TYPE_PDB_PROC_TYPE (gimp_pdb_proc_type_get_type ())
 
 GType gimp_pdb_proc_type_get_type (void) G_GNUC_CONST;
