* 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;
/* 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 {
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);
{
i_free_and_null(storage->error_string);
+ i_free(storage->last_internal_error);
+ storage->last_error_is_internal = FALSE;
storage->error = MAIL_ERROR_NONE;
}
i_free(storage->error_string);
storage->error_string = i_strdup(string);
}
+ storage->last_error_is_internal = FALSE;
storage->error = error;
}
{
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
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)
{
/* 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. */