From e58bba828bffa06364fd5c014ce02f5763328325 Mon Sep 17 00:00:00 2001 From: Jose Dapena Paz Date: Wed, 16 Apr 2008 19:41:22 +0000 Subject: [PATCH] Work to fix bug NB#80656. * src/modest-tny-msg.[ch]: * Added support for fetching errors in tinymail when we add attachments. In particular, now we set an error in copy_mime_stream if it was not successful. * src/modest-ui-actions.c: * If creating message has errors because of stream read failures (i.e. after removing a media or switching down a server in a vfs stream) we go on but avoid adding the message. We also show an information banner. * src/modest-mail-operation.c: * Manage on message creation the case of an error reading attachments so that we don't stop processing and show proper error at the end. * src/modest-error.h: * Added new error for file io (it'll happen when we fail to retrieve an attachment). pmo-trunk-r4424 --- src/modest-error.h | 1 + src/modest-mail-operation.c | 52 +++++++++++++++++++++-------- src/modest-tny-msg.c | 78 +++++++++++++++++++++++++------------------ src/modest-tny-msg.h | 6 ++-- src/modest-ui-actions.c | 9 +++-- 5 files changed, 96 insertions(+), 50 deletions(-) diff --git a/src/modest-error.h b/src/modest-error.h index 11a1803..f78a9f1 100644 --- a/src/modest-error.h +++ b/src/modest-error.h @@ -47,6 +47,7 @@ typedef enum _ModestErrorCode { MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS, /* Folder to be created exists already. */ MODEST_MAIL_OPERATION_ERROR_RETRIEVAL_NUMBER_LIMIT, /* There were too many messages to retrieve. */ MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED, + MODEST_MAIL_OPERATION_ERROR_FILE_IO, /* couldn't retrieve a file to construct a mail */ } ModestErrorCode; G_END_DECLS diff --git a/src/modest-mail-operation.c b/src/modest-mail-operation.c index d818fed..001d4ae 100644 --- a/src/modest-mail-operation.c +++ b/src/modest-mail-operation.c @@ -621,6 +621,10 @@ modest_mail_operation_send_mail (ModestMailOperation *self, send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account)); if (!TNY_IS_SEND_QUEUE(send_queue)) { + if (priv->error) { + g_error_free (priv->error); + priv->error = NULL; + } g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR, MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND, "modest: could not find send queue for account\n"); @@ -634,7 +638,11 @@ modest_mail_operation_send_mail (ModestMailOperation *self, tny_send_queue_add_async (send_queue, msg, NULL, NULL, NULL); modest_tny_send_queue_set_requested_send_receive (MODEST_TNY_SEND_QUEUE (send_queue), FALSE); - priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS; + if (priv->error) { + priv->status = MODEST_MAIL_OPERATION_STATUS_FINISHED_WITH_ERRORS; + } else { + priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS; + } modest_mail_operation_notify_end (self); } @@ -672,12 +680,14 @@ create_msg_thread (gpointer thread_data) if (info->html_body == NULL) { new_msg = modest_tny_msg_new (info->to, info->from, info->cc, info->bcc, info->subject, info->plain_body, - info->attachments_list); + info->attachments_list, + &(priv->error)); } else { new_msg = modest_tny_msg_new_html_plain (info->to, info->from, info->cc, info->bcc, info->subject, info->html_body, info->plain_body, info->attachments_list, - info->images_list); + info->images_list, + &(priv->error)); } if (new_msg) { @@ -694,9 +704,10 @@ create_msg_thread (gpointer thread_data) g_object_unref (G_OBJECT(header)); } else { priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; - g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR, - MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED, - "modest: failed to create a new msg\n"); + if (!priv->error) + g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR, + MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED, + "modest: failed to create a new msg\n"); } @@ -784,13 +795,15 @@ modest_mail_operation_send_new_mail_cb (ModestMailOperation *self, TnyFolder *outbox_folder = NULL; TnyHeader *header = NULL; + priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self); + if (!msg) { + priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; + modest_mail_operation_notify_end (self); goto end; } - priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self); - - if (priv->error) { + if (priv->error && priv->error->code != MODEST_MAIL_OPERATION_ERROR_FILE_IO) { priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; modest_mail_operation_notify_end (self); goto end; @@ -935,9 +948,14 @@ modest_mail_operation_save_to_drafts_add_msg_cb(TnyFolder *self, { ModestMailOperationPrivate *priv = NULL; SaveToDraftsAddMsgInfo *info = (SaveToDraftsAddMsgInfo *) userdata; + GError *io_error = NULL; priv = MODEST_MAIL_OPERATION_GET_PRIVATE(info->mailop); + if (priv->error && priv->error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) { + io_error = priv->error; + priv->error = NULL; + } if (priv->error) { g_warning ("%s: priv->error != NULL", __FUNCTION__); g_error_free(priv->error); @@ -960,10 +978,18 @@ modest_mail_operation_save_to_drafts_add_msg_cb(TnyFolder *self, g_object_unref (G_OBJECT(src_folder)); } - if (!priv->error) - priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS; - else + if (priv->error) { priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; + if (io_error) { + g_error_free (io_error); + io_error = NULL; + } + } else if (io_error) { + priv->error = io_error; + priv->status = MODEST_MAIL_OPERATION_STATUS_FINISHED_WITH_ERRORS; + } else { + priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS; + } /* Call the user callback */ if (info->callback) @@ -1018,7 +1044,7 @@ modest_mail_operation_save_to_drafts_cb (ModestMailOperation *self, } } - if (!priv->error) { + if (!priv->error || priv->error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) { SaveToDraftsAddMsgInfo *cb_info = g_slice_new(SaveToDraftsAddMsgInfo); cb_info->transport_account = g_object_ref(info->transport_account); cb_info->draft_msg = info->draft_msg ? g_object_ref(info->draft_msg) : NULL; diff --git a/src/modest-tny-msg.c b/src/modest-tny-msg.c index 4a9c6b8..b7c761d 100644 --- a/src/modest-tny-msg.c +++ b/src/modest-tny-msg.c @@ -39,6 +39,7 @@ #include #include #include "modest-tny-mime-part.h" +#include #ifdef HAVE_CONFIG_H @@ -51,8 +52,8 @@ static TnyMimePart * add_body_part (TnyMsg *msg, const gchar *body, const gchar *content_type); static TnyMimePart * add_html_body_part (TnyMsg *msg, const gchar *body); -static void add_attachments (TnyMimePart *part, GList *attachments_list, gboolean add_inline); -static void add_images (TnyMsg *msg, GList *attachments_list); +static void add_attachments (TnyMimePart *part, GList *attachments_list, gboolean add_inline, GError **err); +static void add_images (TnyMsg *msg, GList *attachments_list, GError **err); static char * get_content_type(const gchar *s); static gboolean is_ascii(const gchar *s); @@ -60,7 +61,7 @@ static gboolean is_ascii(const gchar *s); TnyMsg* modest_tny_msg_new (const gchar* mailto, const gchar* from, const gchar *cc, const gchar *bcc, const gchar* subject, const gchar *body, - GList *attachments) + GList *attachments, GError **err) { TnyMsg *new_msg; TnyHeader *header; @@ -100,7 +101,7 @@ modest_tny_msg_new (const gchar* mailto, const gchar* from, const gchar *cc, /* Add attachments */ if (attachments) - add_attachments (TNY_MIME_PART (new_msg), attachments, FALSE); + add_attachments (TNY_MIME_PART (new_msg), attachments, FALSE, err); if (header) g_object_unref(header); @@ -111,7 +112,7 @@ TnyMsg* modest_tny_msg_new_html_plain (const gchar* mailto, const gchar* from, const gchar *cc, const gchar *bcc, const gchar* subject, const gchar *html_body, const gchar *plain_body, - GList *attachments, GList *images) + GList *attachments, GList *images, GError **err) { TnyMsg *new_msg; TnyHeader *header; @@ -150,8 +151,8 @@ modest_tny_msg_new_html_plain (const gchar* mailto, const gchar* from, const gch g_free (content_type); /* Add attachments */ - add_attachments (TNY_MIME_PART (new_msg), attachments, FALSE); - add_images (new_msg, images); + add_attachments (TNY_MIME_PART (new_msg), attachments, FALSE, err); + add_images (new_msg, images, err); if (header) g_object_unref(header); @@ -221,7 +222,7 @@ add_html_body_part (TnyMsg *msg, } static TnyMimePart * -copy_mime_part (TnyMimePart *part) +copy_mime_part (TnyMimePart *part, GError **err) { TnyMimePart *result = NULL; const gchar *attachment_content_type; @@ -231,6 +232,7 @@ copy_mime_part (TnyMimePart *part) TnyIterator *iterator; TnyStream *attachment_stream; const gchar *enc; + gint ret; if (TNY_IS_MSG (part)) { g_object_ref (part); @@ -249,12 +251,19 @@ copy_mime_part (TnyMimePart *part) /* fill the stream */ attachment_stream = tny_mime_part_get_decoded_stream (part); enc = tny_mime_part_get_transfer_encoding (part); - tny_stream_reset (attachment_stream); - tny_mime_part_construct (result, - attachment_stream, - attachment_content_type, - enc); - tny_stream_reset (attachment_stream); + if (attachment_stream == NULL) { + if (err != NULL && *err == NULL) + g_set_error (err, MODEST_MAIL_OPERATION_ERROR, MODEST_MAIL_OPERATION_ERROR_FILE_IO, _("TODO: couldn't retrieve attachment")); + g_object_unref (result); + return NULL; + } else { + ret = tny_stream_reset (attachment_stream); + ret = tny_mime_part_construct (result, + attachment_stream, + attachment_content_type, + enc); + ret = tny_stream_reset (attachment_stream); + } /* set other mime part fields */ tny_mime_part_set_filename (result, attachment_filename); @@ -268,13 +277,15 @@ copy_mime_part (TnyMimePart *part) TnyMimePart *subpart = TNY_MIME_PART (tny_iterator_get_current (iterator)); if (subpart) { const gchar *subpart_cid; - TnyMimePart *subpart_copy = copy_mime_part (subpart); - subpart_cid = tny_mime_part_get_content_id (subpart); - tny_mime_part_add_part (result, subpart_copy); - if (subpart_cid) - tny_mime_part_set_content_id (result, subpart_cid); + TnyMimePart *subpart_copy = copy_mime_part (subpart, err); + if (subpart_copy != NULL) { + subpart_cid = tny_mime_part_get_content_id (subpart); + tny_mime_part_add_part (result, subpart_copy); + if (subpart_cid) + tny_mime_part_set_content_id (result, subpart_cid); + g_object_unref (subpart_copy); + } g_object_unref (subpart); - g_object_unref (subpart_copy); } tny_iterator_next (iterator); @@ -287,10 +298,11 @@ copy_mime_part (TnyMimePart *part) } static void -add_attachments (TnyMimePart *part, GList *attachments_list, gboolean add_inline) +add_attachments (TnyMimePart *part, GList *attachments_list, gboolean add_inline, GError **err) { GList *pos; TnyMimePart *attachment_part, *old_attachment; + gint ret; for (pos = (GList *)attachments_list; pos; pos = pos->next) { @@ -298,20 +310,22 @@ add_attachments (TnyMimePart *part, GList *attachments_list, gboolean add_inline if (!tny_mime_part_is_purged (old_attachment)) { const gchar *old_cid; old_cid = tny_mime_part_get_content_id (old_attachment); - attachment_part = copy_mime_part (old_attachment); - tny_mime_part_set_header_pair (attachment_part, "Content-Disposition", - add_inline?"inline":"attachment"); - tny_mime_part_set_transfer_encoding (TNY_MIME_PART (attachment_part), "base64"); - tny_mime_part_add_part (TNY_MIME_PART (part), attachment_part); - if (old_cid) - tny_mime_part_set_content_id (attachment_part, old_cid); - g_object_unref (attachment_part); + attachment_part = copy_mime_part (old_attachment, err); + if (attachment_part != NULL) { + tny_mime_part_set_header_pair (attachment_part, "Content-Disposition", + add_inline?"inline":"attachment"); + tny_mime_part_set_transfer_encoding (TNY_MIME_PART (attachment_part), "base64"); + ret = tny_mime_part_add_part (TNY_MIME_PART (part), attachment_part); + if (old_cid) + tny_mime_part_set_content_id (attachment_part, old_cid); + g_object_unref (attachment_part); + } } } } static void -add_images (TnyMsg *msg, GList *images_list) +add_images (TnyMsg *msg, GList *images_list, GError **err) { TnyMimePart *related_part = NULL; const gchar *content_type; @@ -342,7 +356,7 @@ add_images (TnyMsg *msg, GList *images_list) if (related_part != NULL) { /* TODO: attach images in their proper place */ - add_attachments (related_part, images_list, TRUE); + add_attachments (related_part, images_list, TRUE, err); g_object_unref (related_part); } } @@ -617,7 +631,7 @@ create_reply_forward_mail (TnyMsg *msg, TnyHeader *header, const gchar *from, /* ugly to unref it here instead of in the calling func */ if (!is_reply & !no_text_part) { - add_attachments (TNY_MIME_PART (new_msg), attachments, FALSE); + add_attachments (TNY_MIME_PART (new_msg), attachments, FALSE, NULL); } return new_msg; diff --git a/src/modest-tny-msg.h b/src/modest-tny-msg.h index 40ba3ea..9d61204 100644 --- a/src/modest-tny-msg.h +++ b/src/modest-tny-msg.h @@ -70,6 +70,7 @@ typedef enum _ModestTnyMsgReplyMode { * @subject: subject for the messdage * @body: body for the message * @attachments: a list of attachments (local URIs) + * @error: a pointer for errors in message creation * * create a new TnyMsg with the given parameters * @@ -77,7 +78,7 @@ typedef enum _ModestTnyMsgReplyMode { */ TnyMsg* modest_tny_msg_new (const gchar* mailto, const gchar* mailfrom, const gchar *cc, const gchar *bcc, const gchar* subject, const gchar *body, - GList *attachments); + GList *attachments, GError **err); /** * modest_tny_msg_new_html_plain: @@ -90,6 +91,7 @@ TnyMsg* modest_tny_msg_new (const gchar* mailto, const gchar* mailfrom, const gc * @plain_body: body for the message in plain text * @attachments: a list of attachments (mime parts) * @attachments: a list of images (mime parts) + * @error: a pointer for errors in message creation * * create a new TnyMsg with the given parameters * @@ -98,7 +100,7 @@ TnyMsg* modest_tny_msg_new (const gchar* mailto, const gchar* mailfrom, const gc TnyMsg* modest_tny_msg_new_html_plain (const gchar* mailto, const gchar* mailfrom, const gchar *cc, const gchar *bcc, const gchar* subject, const gchar *html_body, const gchar *plain_body, - GList *attachments, GList *images); + GList *attachments, GList *images, GError **err); /** * modest_tny_msg_find_body_part: diff --git a/src/modest-ui-actions.c b/src/modest-ui-actions.c index 31c6429..765dc88 100644 --- a/src/modest-ui-actions.c +++ b/src/modest-ui-actions.c @@ -749,7 +749,7 @@ modest_ui_actions_compose_msg(ModestWindow *win, body = use_signature ? g_strconcat("\n", signature, NULL) : g_strdup(""); } - msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, body, NULL); + msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, body, NULL, NULL); if (!msg) { g_printerr ("modest: failed to create new msg\n"); goto cleanup; @@ -767,7 +767,7 @@ modest_ui_actions_compose_msg(ModestWindow *win, attachments->data, allowed_size); if (total_size > allowed_size) { - g_warning ("%s: total size: %u", + g_warning ("%s: total size: %u", __FUNCTION__, (unsigned int)total_size); break; } @@ -1032,6 +1032,9 @@ modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op, modest_platform_information_banner ((GtkWidget *) win, NULL, dgettext("ke-recv", "cerm_device_memory_full")); + } else if (error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) { + modest_platform_information_banner ((GtkWidget *) win, + NULL, dgettext ("hildon-common-strings", "sfil_ni_unable_to_open_file_not_found")); } else if (user_data) { modest_platform_information_banner ((GtkWidget *) win, NULL, user_data); @@ -2741,7 +2744,7 @@ modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window) gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name); /* Create the mail operation */ - ModestMailOperation *mail_operation = modest_mail_operation_new (NULL); + ModestMailOperation *mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL); modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation); modest_mail_operation_send_new_mail (mail_operation, -- 1.7.9.5