changeset 22316:884f3c20ff34

lib-storage: Add mailbox_list_last_error_push/pop() These are similar to mail_storage_last_error_push/pop()
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Thu, 06 Jul 2017 17:36:28 +0300
parents 445b89dc8246
children a6ffa40d1c9e
files src/lib-storage/mailbox-list-private.h src/lib-storage/mailbox-list.c src/lib-storage/mailbox-list.h
diffstat 3 files changed, 41 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/mailbox-list-private.h	Mon Jul 10 14:37:04 2017 +0300
+++ b/src/lib-storage/mailbox-list-private.h	Thu Jul 06 17:36:28 2017 +0300
@@ -134,6 +134,7 @@
 	char *error_string;
 	enum mail_error error;
 	bool temporary_error;
+	ARRAY(struct mail_storage_error) error_stack;
 
 	ARRAY(union mailbox_list_module_context *) module_contexts;
 
--- a/src/lib-storage/mailbox-list.c	Mon Jul 10 14:37:04 2017 +0300
+++ b/src/lib-storage/mailbox-list.c	Thu Jul 06 17:36:28 2017 +0300
@@ -784,6 +784,11 @@
 		mailbox_tree_deinit(&list->subscriptions);
 	if (list->changelog != NULL)
 		mailbox_log_free(&list->changelog);
+
+	if (array_is_created(&list->error_stack)) {
+		i_assert(array_count(&list->error_stack) == 0);
+		array_free(&list->error_stack);
+	}
 	list->v.deinit(list);
 }
 
@@ -1905,6 +1910,35 @@
 	return TRUE;
 }
 
+void mailbox_list_last_error_push(struct mailbox_list *list)
+{
+	struct mail_storage_error *err;
+
+	if (!array_is_created(&list->error_stack))
+		i_array_init(&list->error_stack, 2);
+	err = array_append_space(&list->error_stack);
+	err->error_string = i_strdup(list->error_string);
+	err->error = list->error;
+	err->last_error_is_internal = list->last_error_is_internal;
+	if (err->last_error_is_internal)
+		err->last_internal_error = i_strdup(list->last_internal_error);
+}
+
+void mailbox_list_last_error_pop(struct mailbox_list *list)
+{
+	unsigned int count = array_count(&list->error_stack);
+	const struct mail_storage_error *err =
+		array_idx(&list->error_stack, count-1);
+
+	i_free(list->error_string);
+	i_free(list->last_internal_error);
+	list->error_string = err->error_string;
+	list->error = err->error;
+	list->last_error_is_internal = err->last_error_is_internal;
+	list->last_internal_error = err->last_internal_error;
+	array_delete(&list->error_stack, count-1, 1);
+}
+
 int mailbox_list_init_fs(struct mailbox_list *list, const char *driver,
 			 const char *args, const char *root_dir,
 			 struct fs **fs_r, const char **error_r)
--- a/src/lib-storage/mailbox-list.h	Mon Jul 10 14:37:04 2017 +0300
+++ b/src/lib-storage/mailbox-list.h	Thu Jul 06 17:36:28 2017 +0300
@@ -278,6 +278,12 @@
 mailbox_list_get_last_internal_error(struct mailbox_list *list,
 				     enum mail_error *error_r);
 
+/* Save the last error until it's popped. This is useful for cases where the
+   list operation has already failed, but the cleanup code path changes the
+   error to something else unwanted. */
+void mailbox_list_last_error_push(struct mailbox_list *list);
+void mailbox_list_last_error_pop(struct mailbox_list *list);
+
 /* Create a fs based on the settings in the given mailbox_list. */
 int mailbox_list_init_fs(struct mailbox_list *list, const char *driver,
 			 const char *args, const char *root_dir,