# HG changeset patch
# Node ID e9358bbdcc967bb2eab38bf50ebcfd0684a379a9
# Parent  3978d8a6af7f1de301fb6bcc7dd6b80a75ef4253
diff --git a/libpurple/purpleconversation.c b/libpurple/purpleconversation.c
--- a/libpurple/purpleconversation.c
+++ b/libpurple/purpleconversation.c
@@ -72,6 +72,8 @@
 
 	gboolean logging;
 	gboolean drafting;
+
+	GError *error;
 };
 
 enum {
@@ -104,6 +106,7 @@
 	PROP_TYPING_STATE,
 	PROP_LOGGING,
 	PROP_DRAFTING,
+	PROP_ERROR,
 	N_PROPERTIES,
 };
 static GParamSpec *properties[N_PROPERTIES] = {NULL, };
@@ -577,6 +580,9 @@
 		purple_conversation_set_drafting(conversation,
 		                                 g_value_get_boolean(value));
 		break;
+	case PROP_ERROR:
+		purple_conversation_set_error(conversation, g_value_get_boxed(value));
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
 		break;
@@ -696,6 +702,9 @@
 		g_value_set_boolean(value,
 		                    purple_conversation_get_drafting(conversation));
 		break;
+	case PROP_ERROR:
+		g_value_set_boxed(value, purple_conversation_get_error(conversation));
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
 		break;
@@ -776,6 +785,8 @@
 	g_clear_handle_id(&conversation->typing_state_source, g_source_remove);
 	g_clear_pointer(&conversation->last_typing, g_date_time_unref);
 
+	g_clear_error(&conversation->error);
+
 	G_OBJECT_CLASS(purple_conversation_parent_class)->finalize(object);
 }
 
@@ -1239,6 +1250,19 @@
 		FALSE,
 		G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
 
+	/**
+	 * PurpleConversation:error:
+	 *
+	 * An error that was encountered in this conversation. For example, this could
+	 * be a channel connection error or a kick message.
+	 *
+	 * Since: 3.0
+	 */
+	properties[PROP_ERROR] = g_param_spec_boxed(
+		"error", NULL, NULL,
+		G_TYPE_ERROR,
+		G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
 	g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
 
 	/**
@@ -2054,3 +2078,24 @@
 		                         properties[PROP_DRAFTING]);
 	}
 }
+
+GError *
+purple_conversation_get_error(PurpleConversation *conversation) {
+	g_return_val_if_fail(PURPLE_IS_CONVERSATION(conversation), NULL);
+
+	return conversation->error;
+}
+
+void
+purple_conversation_set_error(PurpleConversation *conversation,
+                              GError *error)
+{
+	g_return_if_fail(PURPLE_IS_CONVERSATION(conversation));
+
+	g_clear_error(&conversation->error);
+	if(error != NULL) {
+		conversation->error = g_error_copy(error);
+	}
+
+	g_object_notify_by_pspec(G_OBJECT(conversation), properties[PROP_ERROR]);
+}
diff --git a/libpurple/purpleconversation.h b/libpurple/purpleconversation.h
--- a/libpurple/purpleconversation.h
+++ b/libpurple/purpleconversation.h
@@ -919,6 +919,31 @@
 PURPLE_AVAILABLE_IN_3_0
 void purple_conversation_set_drafting(PurpleConversation *conversation, gboolean drafting);
 
+/**
+ * purple_conversation_get_error:
+ * @conversation: The instance.
+ *
+ * Gets the error of @conversation.
+ *
+ * Returns: (nullable) (transfer none): The error of @conversation or %NULL.
+ *
+ * Since: 3.0
+ */
+PURPLE_AVAILABLE_IN_3_0
+GError *purple_conversation_get_error(PurpleConversation *conversation);
+
+/**
+ * purple_conversation_set_error:
+ * @conversation: The instance.
+ * @error: (nullable) (transfer none): The new error.
+ *
+ * Sets the error of @conversation to @error.
+ *
+ * Since: 3.0
+ */
+PURPLE_AVAILABLE_IN_3_0
+void purple_conversation_set_error(PurpleConversation *conversation, GError *error);
+
 G_END_DECLS
 
 #endif /* PURPLE_CONVERSATION_H */
diff --git a/libpurple/tests/test_conversation.c b/libpurple/tests/test_conversation.c
--- a/libpurple/tests/test_conversation.c
+++ b/libpurple/tests/test_conversation.c
@@ -61,6 +61,8 @@
 	GListModel *members = NULL;
 	char *alias = NULL;
 	char *description = NULL;
+	GError *error = NULL;
+	GError *error1 = NULL;
 	char *global_id = NULL;
 	char *id = NULL;
 	char *name = NULL;
@@ -83,6 +85,8 @@
 	avatar = g_object_new(PURPLE_TYPE_AVATAR, NULL);
 	creator = purple_contact_info_new(NULL);
 	created_on = g_date_time_new_now_utc();
+	error = g_error_new(g_quark_from_static_string("test-conversation"), 0,
+	                    "recipient unavailable");
 	topic_author = purple_contact_info_new(NULL);
 	topic_updated = g_date_time_new_now_utc();
 
@@ -100,6 +104,7 @@
 		"creator", creator,
 		"description", "to describe or not to describe...",
 		"drafting", TRUE,
+		"error", error,
 		"favorite", TRUE,
 		"id", "id1",
 		"logging", TRUE,
@@ -124,6 +129,7 @@
 		"creator", &creator1,
 		"description", &description,
 		"drafting", &drafting,
+		"error", &error1,
 		"favorite", &favorite,
 		"global-id", &global_id,
 		"id", &id,
@@ -166,6 +172,11 @@
 
 	g_assert_true(drafting);
 
+	g_assert_error(error1, error->domain, error->code);
+	g_assert_cmpstr(error1->message, ==, "recipient unavailable");
+	g_clear_error(&error);
+	g_clear_error(&error1);
+
 	g_assert_true(favorite);
 
 	g_assert_cmpstr(global_id, ==, "test-id1");
