diff -up evolution-data-server-3.8.5/camel/camel-imapx-job.c.detect-list-errors evolution-data-server-3.8.5/camel/camel-imapx-job.c --- evolution-data-server-3.8.5/camel/camel-imapx-job.c.detect-list-errors 2013-07-23 07:57:42.000000000 -0400 +++ evolution-data-server-3.8.5/camel/camel-imapx-job.c 2013-12-19 13:42:15.923968414 -0500 @@ -29,6 +29,7 @@ struct _CamelIMAPXRealJob { volatile gint ref_count; GCancellable *cancellable; + GError *error; /* Used for running some jobs synchronously. */ GCond done_cond; @@ -113,6 +114,7 @@ camel_imapx_job_unref (CamelIMAPXJob *jo g_cond_clear (&real_job->done_cond); g_mutex_clear (&real_job->done_mutex); + g_clear_error (&real_job->error); if (real_job->destroy_data != NULL) real_job->destroy_data (real_job->data); @@ -221,7 +223,10 @@ camel_imapx_job_run (CamelIMAPXJob *job, if (cancel_id > 0) g_cancellable_disconnect (cancellable, cancel_id); - return success; + if (success && g_cancellable_set_error_if_cancelled (cancellable, error)) + return FALSE; + + return success && !camel_imapx_job_propagate_error (job, error); } gboolean @@ -348,3 +353,37 @@ camel_imapx_job_get_cancellable (CamelIM return real_job->cancellable; } + +void +camel_imapx_job_set_error (CamelIMAPXJob *job, + const GError *error) +{ + CamelIMAPXRealJob *real_job; + + g_return_if_fail (CAMEL_IS_IMAPX_JOB (job)); + + real_job = (CamelIMAPXRealJob *) job; + + /* do not overwrite errors, the first set is kept */ + if (!real_job->error && error) + real_job->error = g_error_copy (error); +} + +gboolean +camel_imapx_job_propagate_error (CamelIMAPXJob *job, + GError **error) +{ + CamelIMAPXRealJob *real_job; + + g_return_val_if_fail (CAMEL_IS_IMAPX_JOB (job), FALSE); + + real_job = (CamelIMAPXRealJob *) job; + + if (!real_job->error) + return FALSE; + + if (error) + g_propagate_error (error, g_error_copy (real_job->error)); + + return TRUE; +} diff -up evolution-data-server-3.8.5/camel/camel-imapx-job.h.detect-list-errors evolution-data-server-3.8.5/camel/camel-imapx-job.h --- evolution-data-server-3.8.5/camel/camel-imapx-job.h.detect-list-errors 2013-07-23 07:57:56.000000000 -0400 +++ evolution-data-server-3.8.5/camel/camel-imapx-job.h 2013-12-19 13:42:15.923968414 -0500 @@ -81,6 +81,10 @@ CamelFolder * camel_imapx_job_ref_folder void camel_imapx_job_set_folder (CamelIMAPXJob *job, CamelFolder *folder); GCancellable * camel_imapx_job_get_cancellable (CamelIMAPXJob *job); +void camel_imapx_job_set_error (CamelIMAPXJob *job, + const GError *error); +gboolean camel_imapx_job_propagate_error (CamelIMAPXJob *job, + GError **error); G_END_DECLS diff -up evolution-data-server-3.8.5/camel/camel-imapx-server.c.detect-list-errors evolution-data-server-3.8.5/camel/camel-imapx-server.c --- evolution-data-server-3.8.5/camel/camel-imapx-server.c.detect-list-errors 2013-12-19 13:27:59.033552530 -0500 +++ evolution-data-server-3.8.5/camel/camel-imapx-server.c 2013-12-19 13:42:15.925968140 -0500 @@ -2772,6 +2772,7 @@ imapx_completion (CamelIMAPXServer *is, CamelIMAPXCommand *ic; gboolean success; guint tag; + GError *local_error = NULL; /* Given "A0001 ...", 'A' = tag prefix, '0001' = tag. */ @@ -2829,18 +2830,40 @@ imapx_completion (CamelIMAPXServer *is, return FALSE; } + camel_imapx_command_ref (ic); camel_imapx_command_queue_remove (is->done, ic); QUEUE_UNLOCK (is); - ic->status = imapx_parse_status (stream, cancellable, error); + ic->status = imapx_parse_status (stream, cancellable, &local_error); + + if (ic->status == NULL || local_error) { + if (!local_error) + local_error = g_error_new_literal (CAMEL_IMAPX_ERROR, 1, "command parse status failed without error set"); + + camel_imapx_job_set_error (camel_imapx_command_get_job (ic), local_error); + g_propagate_error (error, local_error); + + camel_imapx_command_unref (ic); - if (ic->status == NULL) return FALSE; + } + + if (ic->complete != NULL) { + if (!ic->complete (is, ic, cancellable, &local_error) || local_error) { + if (!local_error) + local_error = g_error_new_literal (CAMEL_IMAPX_ERROR, 1, "command complete failed without error set"); + + camel_imapx_job_set_error (camel_imapx_command_get_job (ic), local_error); + g_propagate_error (error, local_error); + + camel_imapx_command_unref (ic); - if (ic->complete != NULL) - if (!ic->complete (is, ic, cancellable, error)) return FALSE; + } + } + + camel_imapx_command_unref (ic); QUEUE_LOCK (is); success = imapx_command_start_next (is, cancellable, error); diff -up evolution-data-server-3.8.5/camel/camel-imapx-store.c.detect-list-errors evolution-data-server-3.8.5/camel/camel-imapx-store.c --- evolution-data-server-3.8.5/camel/camel-imapx-store.c.detect-list-errors 2013-12-19 13:27:59.028552534 -0500 +++ evolution-data-server-3.8.5/camel/camel-imapx-store.c 2013-12-19 13:42:15.926968007 -0500 @@ -1011,11 +1011,15 @@ fetch_folders_for_pattern (CamelIMAPXSto GError **error) { GPtrArray *folders; + GError *local_error = NULL; folders = camel_imapx_server_list ( - server, pattern, flags, ext, cancellable, error); - if (folders == NULL) + server, pattern, flags, ext, cancellable, &local_error); + if (folders == NULL || local_error) { + if (local_error) + g_propagate_error (error, local_error); return FALSE; + } add_folders_to_summary (istore, server, folders, table, (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED));