Index: plugins/bogo-junk-plugin/bf-junk-filter.c
===================================================================
--- plugins/bogo-junk-plugin/bf-junk-filter.c	(revision 35413)
+++ plugins/bogo-junk-plugin/bf-junk-filter.c	(working copy)
@@ -73,9 +73,8 @@ int e_plugin_lib_enable (EPluginLib *ep,
 
 static gboolean em_junk_bf_unicode = TRUE;
 
-
 static gint
-pipe_to_bogofilter (CamelMimeMessage *msg, gchar **argv)
+pipe_to_bogofilter (CamelMimeMessage *msg, gchar **argv, GError **error)
 {
 	GPid child_pid;
 	gint bf_in;
@@ -83,6 +82,7 @@ pipe_to_bogofilter (CamelMimeMessage *ms
 	GError *err = NULL;
 	gint status;
 	gint waitres;
+	gint res;
 
 	if (camel_debug_start ("junk")) {
 		int i;
@@ -110,6 +110,10 @@ pipe_to_bogofilter (CamelMimeMessage *ms
 		g_warning ("error occurred while spawning %s: %s",
 		           argv[0],
 		           err->message);
+		if (error) {
+			/* For Translators: The first %s stands for the executable full path with a file name, the second is the error message itself. */
+			*error = g_error_new (EM_JUNK_ERROR, err->code, _("Error occurred while spawning %s: %s."), argv[0], err->message);
+		}
 		return BOGOFILTER_ERROR;
 	}
 
@@ -132,16 +136,24 @@ pipe_to_bogofilter (CamelMimeMessage *ms
 			kill (child_pid, SIGKILL);
 			sleep (1);
 			waitres = waitpid (child_pid, &status, WNOHANG);
-		}
+			if (error)
+				*error = g_error_new (EM_JUNK_ERROR, -2, _("Bogofilter child process does not respond, killing..."));
+		} else if (error)
+			*error = g_error_new (EM_JUNK_ERROR, -3, _("Wait for Bogofilter child process interrupted, terminating..."));
 	}
 
 	g_spawn_close_pid (child_pid);
 
 	if (waitres >= 0 && WIFEXITED (status)) {
-		return WEXITSTATUS (status);
+		res = WEXITSTATUS (status);
 	} else {
-		return BOGOFILTER_ERROR;
+		res = BOGOFILTER_ERROR;
 	}
+
+	if (res != 0 && error && !*error)
+		*error = g_error_new (EM_JUNK_ERROR, res, _("Pipe to Bogofilter failed, error code: %d."), res);
+
+	return res;
 }
 
 static void
@@ -190,7 +202,7 @@ em_junk_bf_check_junk (EPlugin *ep, EMJu
 		argv[1] = "--unicode=yes";
 	}
 
-	rv = pipe_to_bogofilter (msg, argv);
+	rv = pipe_to_bogofilter (msg, argv, &target->error);
 
 	d(fprintf (stderr, "em_junk_bf_check_junk rv = %d\n", rv));
 
@@ -215,7 +227,7 @@ em_junk_bf_report_junk (EPlugin *ep, EMJ
 		argv[2] = "--unicode=yes";
 	}
 
-	pipe_to_bogofilter (msg, argv);
+	pipe_to_bogofilter (msg, argv, &target->error);
 }
 
 void
@@ -236,7 +248,7 @@ em_junk_bf_report_non_junk (EPlugin *ep,
 		argv[2] = "--unicode=yes";
 	}
 
-	pipe_to_bogofilter (msg, argv);
+	pipe_to_bogofilter (msg, argv, &target->error);
 }
 
 void
Index: plugins/bogo-junk-plugin/ChangeLog
===================================================================
--- plugins/bogo-junk-plugin/ChangeLog	(revision 35413)
+++ plugins/bogo-junk-plugin/ChangeLog	(working copy)
@@ -1,3 +1,11 @@
+2008-04-25  Milan Crha  <mcrha@redhat.com>
+
+	** Fix for bug #273041
+
+	* bf-junk-filter.c: (pipe_to_bogofilter), (em_junk_bf_check_junk),
+	(em_junk_bf_report_junk), (em_junk_bf_report_non_junk):
+	Propagate possible errors to the UI.
+
 2008-03-19  Sankar P  <psankar@novell.com>
 
 	** Fix for bug #519304
Index: plugins/sa-junk-plugin/ChangeLog
===================================================================
--- plugins/sa-junk-plugin/ChangeLog	(revision 35413)
+++ plugins/sa-junk-plugin/ChangeLog	(working copy)
@@ -1,3 +1,16 @@
+2008-04-25  Milan Crha  <mcrha@redhat.com>
+
+	** Fix for bug #273041
+
+	* em-junk-filter.c: (em_junk_sa_commit_reports),
+	(em_junk_sa_validate_binary): Fix function prototype.
+	* em-junk-filter.c: (pipe_to_sa_full), (em_junk_sa_test_spamd_running),
+	(em_junk_sa_test_spamassassin),	(pipe_to_sa), (em_junk_sa_run_spamd),
+	(em_junk_sa_test_spamd), (em_junk_sa_is_available),
+	(em_junk_sa_check_junk), (get_spamassassin_version),
+	(em_junk_sa_report_junk), (em_junk_sa_report_non_junk):
+	Propagate possible errors to the UI.
+
 2008-03-13  Milan Crha  <mcrha@redhat.com>
 
 	** Fix for bug #515786
Index: plugins/sa-junk-plugin/em-junk-filter.c
===================================================================
--- plugins/sa-junk-plugin/em-junk-filter.c	(revision 35413)
+++ plugins/sa-junk-plugin/em-junk-filter.c	(working copy)
@@ -64,8 +64,8 @@ int e_plugin_lib_enable (EPluginLib *ep,
 gboolean em_junk_sa_check_junk (EPlugin *ep, EMJunkHookTarget *target);
 void em_junk_sa_report_junk (EPlugin *ep, EMJunkHookTarget *target);
 void em_junk_sa_report_non_junk (EPlugin *ep, EMJunkHookTarget *target);
-void em_junk_sa_commit_reports (EPlugin *ep, EMJunkHookTarget *target);
-void *em_junk_sa_validate_binary (EPlugin *ep, EMJunkHookTarget *target);
+void em_junk_sa_commit_reports (EPlugin *ep);
+void *em_junk_sa_validate_binary (EPlugin *ep);
 GtkWidget *org_gnome_sa_use_remote_tests (struct _EPlugin *epl, struct _EConfigHookItemFactoryData *data);
 
 static void em_junk_sa_init (void);
@@ -110,7 +110,7 @@ em_junk_sa_get_name (void)
 #endif
 
 static int
-pipe_to_sa_full (CamelMimeMessage *msg, const char *in, char **argv, int rv_err, int wait_for_termination, GByteArray *output_buffer)
+pipe_to_sa_full (CamelMimeMessage *msg, const char *in, char **argv, int rv_err, int wait_for_termination, GByteArray *output_buffer, GError **error)
 {
 	int result, status, errnosav, fds[2], out_fds[2];
 	CamelStream *stream;
@@ -131,6 +131,8 @@ pipe_to_sa_full (CamelMimeMessage *msg, 
 	program = g_find_program_in_path (argv [0]);
 	if (program == NULL) {
 		d(printf ("program not found, returning %d\n", rv_err));
+		if (error && !*error)
+			*error = g_error_new (EM_JUNK_ERROR, rv_err, _("SpamAssassin not found, code: %d"), rv_err);
 		return rv_err;
 	}
 	g_free (program);
@@ -138,6 +140,8 @@ pipe_to_sa_full (CamelMimeMessage *msg, 
 	if (pipe (fds) == -1) {
 		errnosav = errno;
 		d(printf ("failed to create a pipe (for use with spamassassin: %s\n", strerror (errno)));
+		if (error && !*error)
+			*error = g_error_new (EM_JUNK_ERROR, errnosav, _("Failed to create pipe: %s"), strerror (errnosav));
 		errno = errnosav;
 		return rv_err;
 	}
@@ -145,6 +149,8 @@ pipe_to_sa_full (CamelMimeMessage *msg, 
 	if (output_buffer && pipe (out_fds) == -1) {
 		errnosav = errno;
 		d(printf ("failed to create a pipe (for use with spamassassin: %s\n", strerror (errno)));
+		if (error && !*error)
+			*error = g_error_new (EM_JUNK_ERROR, errnosav, _("Failed to create pipe: %s"), strerror (errnosav));
 		close (fds [0]);
 		close (fds [1]);
 		errno = errnosav;
@@ -182,6 +188,8 @@ pipe_to_sa_full (CamelMimeMessage *msg, 
 			close (out_fds [0]);
 			close (out_fds [1]);
 		}
+		if (error && !*error && (errnosav != 0 && errnosav != -1))
+			*error = g_error_new (EM_JUNK_ERROR, errnosav, _("Error after fork: %s"), strerror (errnosav));
 		errno = errnosav;
 		return rv_err;
 	}
@@ -219,6 +227,8 @@ pipe_to_sa_full (CamelMimeMessage *msg, 
 	}
 
 	if (wait_for_termination) {
+		int res;
+
 		d(printf ("wait for child %d termination\n", pid));
 		result = waitpid (pid, &status, 0);
 
@@ -234,21 +244,29 @@ pipe_to_sa_full (CamelMimeMessage *msg, 
 				kill (pid, SIGKILL);
 				sleep (1);
 				result = waitpid (pid, &status, WNOHANG);
-			}
+				if (error && !*error)
+					*error = g_error_new (EM_JUNK_ERROR, -2, _("SpamAssassin child process does not respond, killing..."));
+			} else if (error && !*error)
+				*error = g_error_new (EM_JUNK_ERROR, -3, _("Wait for Spamassassin child process interrupted, terminating..."));
 		}
 
 		if (result != -1 && WIFEXITED (status))
-			return WEXITSTATUS (status);
+			res = WEXITSTATUS (status);
 		else
-			return rv_err;
+			res = rv_err;
+
+		if (res != 0 && error && !*error)
+			*error = g_error_new (EM_JUNK_ERROR, res, _("Pipe to SpamAssassin failed, error code: %d"), res);
+
+		return res;
 	} else
 		return 0;
 }
 
 static int
-pipe_to_sa (CamelMimeMessage *msg, const char *in, char **argv)
+pipe_to_sa (CamelMimeMessage *msg, const char *in, char **argv, GError **error)
 {
-	return pipe_to_sa_full (msg, in, argv, -1, 1, NULL);
+	return pipe_to_sa_full (msg, in, argv, -1, 1, NULL, error);
 }
 
 static char *
@@ -281,7 +299,7 @@ em_junk_sa_test_spamd_running (char *bin
 
 	argv[i] = NULL;
 
-	rv = pipe_to_sa (NULL, "From test@127.0.0.1", argv) == 0;
+	rv = pipe_to_sa (NULL, "From test@127.0.0.1", argv, NULL) == 0;
 
 	d(fprintf (stderr, "result: %d (%s)\n", rv, rv ? "success" : "failed"));
 
@@ -299,7 +317,7 @@ em_junk_sa_test_spamassassin (void)
 		NULL,
 	};
 
-	if (pipe_to_sa (NULL, NULL, argv) != 0)
+	if (pipe_to_sa (NULL, NULL, argv, NULL) != 0)
 		em_junk_sa_available = FALSE;
 	else
 		em_junk_sa_available = TRUE;
@@ -337,7 +355,7 @@ em_junk_sa_run_spamd (char *binary)
 
 	d(fprintf (stderr, "trying to run %s with socket path %s\n", binary, em_junk_sa_get_socket_path ()));
 
-	if (!pipe_to_sa_full (NULL, NULL, argv, -1, 0, NULL)) {
+	if (!pipe_to_sa_full (NULL, NULL, argv, -1, 0, NULL, NULL)) {
 		struct timespec time_req;
 		struct stat stat_buf;
 
@@ -427,7 +445,7 @@ em_junk_sa_test_spamd (void)
 		   argv [i++] = "ps ax|grep -v grep|grep -E 'spamd.*(\\-L|\\-\\-local)'|grep -E -v '\\ \\-p\\ |\\ \\-\\-port\\ '";
 		   argv[i] = NULL;
 
-		   if (pipe_to_sa (NULL, NULL, argv) != 0) {
+		   if (pipe_to_sa (NULL, NULL, argv, NULL) != 0) {
 			   try_system_spamd = FALSE;
 			   d(fprintf (stderr, "there's no system spamd with -L/--local parameter running\n"));
 		   }
@@ -470,7 +488,7 @@ em_junk_sa_test_spamd (void)
 }
 
 static gboolean
-em_junk_sa_is_available (void)
+em_junk_sa_is_available (GError **error)
 {
 	pthread_mutex_lock (&em_junk_sa_init_lock);
 
@@ -480,6 +498,10 @@ em_junk_sa_is_available (void)
 	if (em_junk_sa_available && !em_junk_sa_spamd_tested && em_junk_sa_use_daemon)
 		em_junk_sa_test_spamd ();
 
+	if (error && !em_junk_sa_available) {
+		*error = g_error_new (EM_JUNK_ERROR, 1, _("SpamAssassin is not available."));
+	}
+
 	pthread_mutex_unlock (&em_junk_sa_init_lock);
 
 	return em_junk_sa_available;
@@ -549,7 +571,7 @@ em_junk_sa_check_junk(EPlugin *ep, EMJun
 
 	d(fprintf (stderr, "em_junk_sa_check_junk\n"));
 
-	if (!em_junk_sa_is_available ())
+	if (!em_junk_sa_is_available (&target->error))
 		return FALSE;
 
 	if (em_junk_sa_use_spamc && em_junk_sa_use_daemon) {
@@ -575,7 +597,7 @@ em_junk_sa_check_junk(EPlugin *ep, EMJun
 
 	argv[i] = NULL;
 
-	rv = pipe_to_sa_full (msg, NULL, argv, 0, 1, out) != 0;
+	rv = pipe_to_sa_full (msg, NULL, argv, 0, 1, out, &target->error) != 0;
 
 	if (!rv && out && !strcmp ((const char *)out->data, "0/0\n")) {
 		/* an error occurred */
@@ -587,7 +609,7 @@ em_junk_sa_check_junk(EPlugin *ep, EMJun
 			argv [socket_i] = to_free = g_strdup (em_junk_sa_get_socket_path ());
 			pthread_mutex_unlock (&em_junk_sa_preferred_socket_path_lock);
 
-			rv = pipe_to_sa_full (msg, NULL, argv, 0, 1, out) != 0;
+			rv = pipe_to_sa_full (msg, NULL, argv, 0, 1, out, &target->error) != 0;
 		} else if (!em_junk_sa_use_spamc)
 			/* in case respawning were too fast we fallback to spamassassin */
 			rv = em_junk_sa_check_junk (ep, target);
@@ -618,7 +640,7 @@ get_spamassassin_version ()
 	if (!em_junk_sa_checked_spamassassin_version){
 		out = g_byte_array_new ();
 
-		if (pipe_to_sa_full (NULL, NULL, argv, -1, 1, out) != 0){
+		if (pipe_to_sa_full (NULL, NULL, argv, -1, 1, out, NULL) != 0){
 			if(out)
 				g_byte_array_free (out, TRUE);
 			return em_junk_sa_spamassassin_version;
@@ -662,12 +684,12 @@ em_junk_sa_report_junk (EPlugin *ep, EMJ
 
 	d(fprintf (stderr, "em_junk_sa_report_junk\n"));
 
-	if (em_junk_sa_is_available ()) {
+	if (em_junk_sa_is_available (&target->error)) {
 		if (em_junk_sa_local_only)
 			argv[4] = "--local";
 
 		pthread_mutex_lock (&em_junk_sa_report_lock);
-		pipe_to_sa (msg, NULL, argv);
+		pipe_to_sa (msg, NULL, argv, &target->error);
 		pthread_mutex_unlock (&em_junk_sa_report_lock);
 	}
 }
@@ -688,18 +710,18 @@ em_junk_sa_report_non_junk (EPlugin *ep,
 
 	d(fprintf (stderr, "em_junk_sa_report_notjunk\n"));
 
-	if (em_junk_sa_is_available ()) {
+	if (em_junk_sa_is_available (&target->error)) {
 		if (em_junk_sa_local_only)
 			argv[4] = "--local";
 
 		pthread_mutex_lock (&em_junk_sa_report_lock);
-		pipe_to_sa (msg, NULL, argv);
+		pipe_to_sa (msg, NULL, argv, &target->error);
 		pthread_mutex_unlock (&em_junk_sa_report_lock);
 	}
 }
 
 void
-em_junk_sa_commit_reports (EPlugin *ep, EMJunkHookTarget *target)
+em_junk_sa_commit_reports (EPlugin *ep)
 {
 	char *sync_op = ((get_spamassassin_version () >= 3) ? "--sync": "--rebuild");
 	char *argv[4] = {
@@ -711,20 +733,20 @@ em_junk_sa_commit_reports (EPlugin *ep, 
 
 	d(fprintf (stderr, "em_junk_sa_commit_reports\n"));
 
-	if (em_junk_sa_is_available ()) {
+	if (em_junk_sa_is_available (NULL)) {
 		if (em_junk_sa_local_only)
 			argv[2] = "--local";
 
 		pthread_mutex_lock (&em_junk_sa_report_lock);
-		pipe_to_sa (NULL, NULL, argv);
+		pipe_to_sa (NULL, NULL, argv, NULL);
 		pthread_mutex_unlock (&em_junk_sa_report_lock);
 	}
 }
 
 void *
-em_junk_sa_validate_binary (EPlugin *ep, EMJunkHookTarget *target)
+em_junk_sa_validate_binary (EPlugin *ep)
 {
-	return em_junk_sa_is_available () ? "1" : NULL;
+	return em_junk_sa_is_available (NULL) ? "1" : NULL;
 }
 
 static void
Index: mail/ChangeLog
===================================================================
--- mail/ChangeLog	(revision 35413)
+++ mail/ChangeLog	(working copy)
@@ -1,3 +1,14 @@
+2008-04-25  Milan Crha  <mcrha@redhat.com>
+
+	** Fix for bug #273041
+
+	* mail.error.xml: (junk-check-error), (junk-report-error),
+	(junk-not-report-error): New error messages added.
+	* em-junk-hook.h: (struct _EMJunkHookTarget), (em_junk_error_quark):
+	* em-junk-hook.c: (manage_error), (em_junk_check_junk),
+	(em_junk_report_junk), (em_junk_report_non_junk):
+	Allow propagation of the error from the plugin in the hook target.
+
 2008-04-23  Milan Crha  <mcrha@redhat.com>
 
 	* em-format-html-display.c: (efhd_update_bar):
Index: mail/mail.error.xml
===================================================================
--- mail/mail.error.xml	(revision 35413)
+++ mail/mail.error.xml	(working copy)
@@ -411,6 +411,19 @@ You can choose to ignore this folder, ov
     <_secondary xml:space="preserve">You do not have sufficient permissions to delete this mail.</_secondary>
   </error>
 
+  <error id="junk-check-error" type="error">
+    <_primary>Check Junk Failed</_primary>
+    <_secondary xml:space="preserve">{0}</_secondary>
+  </error>
+
+  <error id="junk-report-error" type="error">
+    <_primary>Report Junk Failed</_primary>
+    <_secondary xml:space="preserve">{0}</_secondary>
+  </error>
 
+  <error id="junk-not-report-error" type="error">
+    <_primary>Report Not Junk Failed</_primary>
+    <_secondary xml:space="preserve">{0}</_secondary>
+  </error>
 </error-list>
 
Index: mail/em-junk-hook.c
===================================================================
--- mail/em-junk-hook.c	(revision 35413)
+++ mail/em-junk-hook.c	(working copy)
@@ -30,6 +30,8 @@
 #include "em-junk-hook.h"
 #include "mail-session.h"
 #include <e-util/e-icon-factory.h>
+#include "e-util/e-error.h"
+#include "em-utils.h"
 #include <camel/camel-junk-plugin.h>
 #include <glib/gi18n.h>
 
@@ -61,6 +63,15 @@ static const EPluginHookTargetKey emjh_f
   </hook>
 
 */
+
+static void manage_error (const char *msg, GError *error);
+
+GQuark
+em_junk_error_quark (void)
+{
+	return g_quark_from_static_string ("em-junk-error-quark");
+}
+
 static const char *
 em_junk_get_name (CamelJunkPlugin *csp);
 
@@ -90,11 +101,17 @@ em_junk_check_junk(CamelJunkPlugin *csp,
 	struct _EMJunkHookItem *item = (EMJunkHookItem *)csp;
 
 	if (item->hook && item->hook->hook.plugin->enabled) {
+		gboolean res;
 		EMJunkHookTarget target = {
-			  m
+			m,
+			NULL
 		};
 
-		return e_plugin_invoke(item->hook->hook.plugin, item->check_junk, &target) != NULL;
+		res = e_plugin_invoke(item->hook->hook.plugin, item->check_junk, &target) != NULL;
+
+		manage_error ("mail:junk-check-error", target.error);
+
+		return res;
 	}
 
 	return FALSE;
@@ -107,10 +124,13 @@ em_junk_report_junk(CamelJunkPlugin *csp
 
 	if (item->hook && item->hook->hook.plugin->enabled) {
 		EMJunkHookTarget target = {
-			  m
+			m,
+			NULL
 		};
 
 		e_plugin_invoke(item->hook->hook.plugin, item->report_junk, &target);
+
+		manage_error ("mail:junk-report-error", target.error);
 	}
 }
 
@@ -121,9 +141,11 @@ em_junk_report_non_junk(CamelJunkPlugin 
 
 	if (item->hook && item->hook->hook.plugin->enabled) {
 		EMJunkHookTarget target = {
-			 m
+			m,
+			NULL
 		};
 		e_plugin_invoke(item->hook->hook.plugin, item->report_non_junk, &target);
+		manage_error ("mail:junk-not-report-error", target.error);
 	}
 }
 
@@ -279,6 +301,20 @@ emjh_construct(EPluginHook *eph, EPlugin
 	return 0;
 }
 
+static void
+manage_error (const char *msg, GError *error)
+{
+	GtkWidget *w;
+
+	if (!error)
+		return;
+
+	w = e_error_new (NULL, msg, error->message, NULL);
+	em_utils_show_error_silent (w);
+
+	g_error_free (error);
+}
+
 /*XXX: don't think we need here*/
 static void
 emjh_enable(EPluginHook *eph, int state)
Index: mail/em-junk-hook.h
===================================================================
--- mail/em-junk-hook.h	(revision 35413)
+++ mail/em-junk-hook.h	(working copy)
@@ -43,8 +43,13 @@ typedef struct _EMJunkHookTarget EMJunkH
 
 typedef void (*EMJunkHookFunc)(struct _EPlugin *plugin, EMJunkHookTarget *data);
 
+GQuark em_junk_error_quark (void);
+
+#define EM_JUNK_ERROR em_junk_error_quark ()
+
 struct _EMJunkHookTarget {
 	struct _CamelMimeMessage *m;
+	GError *error;
 };
 
 struct _EMJunkHookItem {
