]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Add mail_storage_get_last_internal_error()
authorMartti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
Thu, 16 Mar 2017 09:12:29 +0000 (11:12 +0200)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Mon, 27 Mar 2017 09:58:06 +0000 (12:58 +0300)
This returns the error given to mail_storage_set_critical().

src/lib-storage/mail-storage-private.h
src/lib-storage/mail-storage.c
src/lib-storage/mail-storage.h

index 48a39f4168e4252f0958559fd67ed73e9aa23004..7e7239edb975008ce71786ce80f3e7063568972c 100644 (file)
@@ -128,6 +128,9 @@ struct mail_storage {
         * uniqueness checking (via strcmp) and never used as a path. */
        const char *unique_root_dir;
 
+       /* Last error set in mail_storage_set_critical(). */
+       char *last_internal_error;
+
        char *error_string;
        enum mail_error error;
        ARRAY(struct mail_storage_error) error_stack;
@@ -152,6 +155,7 @@ struct mail_storage {
 
        /* Failed to create shared attribute dict, don't try again */
        unsigned int shared_attr_dict_failed:1;
+       unsigned int last_error_is_internal:1;
 };
 
 struct mail_attachment_part {
index 1a215f0e249eb63ab15485fa5b9ec38d9cc2a8fd..a9206b2142bf80e6cb80bee064a9f88154e3361f 100644 (file)
@@ -452,6 +452,7 @@ void mail_storage_unref(struct mail_storage **_storage)
        DLLIST_REMOVE(&storage->user->storages, storage);
 
        storage->v.destroy(storage);
+       i_free(storage->last_internal_error);
        i_free(storage->error_string);
        if (array_is_created(&storage->error_stack)) {
                i_assert(array_count(&storage->error_stack) == 0);
@@ -487,6 +488,8 @@ void mail_storage_clear_error(struct mail_storage *storage)
 {
        i_free_and_null(storage->error_string);
 
+       i_free(storage->last_internal_error);
+       storage->last_error_is_internal = FALSE;
        storage->error = MAIL_ERROR_NONE;
 }
 
@@ -497,6 +500,7 @@ void mail_storage_set_error(struct mail_storage *storage,
                i_free(storage->error_string);
                storage->error_string = i_strdup(string);
        }
+       storage->last_error_is_internal = FALSE;
        storage->error = error;
 }
 
@@ -516,9 +520,12 @@ void mail_storage_set_critical(struct mail_storage *storage,
 {
        va_list va;
 
+       i_free(storage->last_internal_error);
        va_start(va, fmt);
-       i_error("%s", t_strdup_vprintf(fmt, va));
+       storage->last_internal_error = i_strdup_vprintf(fmt, va);
        va_end(va);
+       storage->last_error_is_internal = TRUE;
+       i_error("%s", storage->last_internal_error);
 
        /* critical errors may contain sensitive data, so let user
           see only "Internal error" with a timestamp to make it
@@ -526,6 +533,25 @@ void mail_storage_set_critical(struct mail_storage *storage,
        mail_storage_set_internal_error(storage);
 }
 
+const char *mail_storage_get_last_internal_error(struct mail_storage *storage,
+                                                enum mail_error *error_r)
+{
+       if (error_r != NULL)
+               *error_r = storage->error;
+       if (storage->last_error_is_internal) {
+               i_assert(storage->last_internal_error != NULL);
+               return storage->last_internal_error;
+       }
+       return mail_storage_get_last_error(storage, error_r);
+}
+
+const char *mailbox_get_last_internal_error(struct mailbox *box,
+                                           enum mail_error *error_r)
+{
+       return mail_storage_get_last_internal_error(mailbox_get_storage(box),
+                                                   error_r);
+}
+
 void mail_storage_copy_error(struct mail_storage *dest,
                             struct mail_storage *src)
 {
index 06207e8dcf826e74324220c30eec6ee1a672d65d..3dc77dd449111b1c04ec447435cc62746e549dbe 100644 (file)
@@ -481,6 +481,14 @@ mailbox_get_last_error(struct mailbox *box, enum mail_error *error_r)
 /* Wrapper for mail_storage_get_last_error(); */
 enum mail_error mailbox_get_last_mail_error(struct mailbox *box);
 
+const char * ATTR_NOWARN_UNUSED_RESULT
+mail_storage_get_last_internal_error(struct mail_storage *storage,
+                                    enum mail_error *error_r) ATTR_NULL(2);
+/* Wrapper for mail_storage_get_last_internal_error(); */
+const char * ATTR_NOWARN_UNUSED_RESULT
+mailbox_get_last_internal_error(struct mailbox *box,
+                               enum mail_error *error_r) ATTR_NULL(2);
+
 /* Save the last error until it's popped. This is useful for cases where the
    storage has already failed, but the cleanup code path changes the error to
    something else unwanted. */