Index: protocols/jabber/conference.c
===================================================================
--- protocols/jabber/conference.c	(revision 4306d8b066d335cb6667414bdd6c5b2e78ccbfd5)
+++ protocols/jabber/conference.c	(revision 5bd21df87b195af211c2280ca00391493a669895)
@@ -24,4 +24,6 @@
 #include "jabber.h"
 
+static xt_status jabber_chat_join_failed( struct im_connection *ic, struct xt_node *node, struct xt_node *orig );
+
 struct groupchat *jabber_chat_join( struct im_connection *ic, char *room, char *nick, char *password )
 {
@@ -35,12 +37,11 @@
 	xt_add_attr( node, "xmlns", XMLNS_MUC );
 	node = jabber_make_packet( "presence", NULL, roomjid, node );
+	jabber_cache_add( ic, node, jabber_chat_join_failed );
 	
 	if( !jabber_write_packet( ic, node ) )
 	{
 		g_free( roomjid );
-		xt_free_node( node );
 		return NULL;
 	}
-	xt_free_node( node );
 	
 	jc = g_new0( struct jabber_chat, 1 );
@@ -63,4 +64,43 @@
 	
 	return c;
+}
+
+static xt_status jabber_chat_join_failed( struct im_connection *ic, struct xt_node *node, struct xt_node *orig )
+{
+	struct jabber_error *err;
+	struct jabber_buddy *bud;
+	char *room;
+	
+	room = xt_find_attr( orig, "to" );
+	bud = jabber_buddy_by_jid( ic, room, 0 );
+	
+	err = jabber_error_parse( xt_find_node( node->children, "error" ), XMLNS_STANZA_ERROR );
+	if( err )
+	{
+		imcb_error( ic, "Error joining groupchat %s: %s%s%s",
+		            bud->bare_jid, err->code, err->text ? ": " : "",
+		            err->text ? err->text : "" );
+		jabber_error_free( err );
+	}
+	
+	if( bud )
+		jabber_chat_free( jabber_chat_by_jid( ic, bud->bare_jid ) );
+}
+
+struct groupchat *jabber_chat_by_jid( struct im_connection *ic, const char *name )
+{
+	char *normalized = jabber_normalize( name );
+	struct groupchat *ret;
+	struct jabber_chat *jc;
+	
+	for( ret = ic->groupchats; ret; ret = ret->next )
+	{
+		jc = ret->data;
+		if( strcmp( normalized, jc->name ) == 0 )
+			break;
+	}
+	g_free( normalized );
+	
+	return ret;
 }
 
@@ -148,5 +188,5 @@
 	char *s;
 	
-	if( ( chat = jabber_chat_by_name( ic, bud->bare_jid ) ) == NULL )
+	if( ( chat = jabber_chat_by_jid( ic, bud->bare_jid ) ) == NULL )
 	{
 		/* How could this happen?? We could do kill( self, 11 )
@@ -250,5 +290,5 @@
 		return;
 	}
-	else if( ( chat = jabber_chat_by_name( ic, bud->bare_jid ) ) == NULL )
+	else if( ( chat = jabber_chat_by_jid( ic, bud->bare_jid ) ) == NULL )
 	{
 		/* How could this happen?? We could do kill( self, 11 )
Index: protocols/jabber/jabber.c
===================================================================
--- protocols/jabber/jabber.c	(revision 4306d8b066d335cb6667414bdd6c5b2e78ccbfd5)
+++ protocols/jabber/jabber.c	(revision 5bd21df87b195af211c2280ca00391493a669895)
@@ -270,5 +270,5 @@
 		return jabber_write( ic, message, strlen( message ) );
 	
-	if( ( s = strchr( who, '=' ) ) && jabber_chat_by_name( ic, s + 1 ) )
+	if( ( s = strchr( who, '=' ) ) && jabber_chat_by_jid( ic, s + 1 ) )
 		bud = jabber_buddy_by_ext_jid( ic, who, 0 );
 	else
@@ -397,5 +397,5 @@
 	if( strchr( room, '@' ) == NULL )
 		imcb_error( ic, "Invalid room name: %s", room );
-	else if( jabber_chat_by_name( ic, room ) )
+	else if( jabber_chat_by_jid( ic, room ) )
 		imcb_error( ic, "Already present in chat `%s'", room );
 	else
Index: protocols/jabber/jabber.h
===================================================================
--- protocols/jabber/jabber.h	(revision 4306d8b066d335cb6667414bdd6c5b2e78ccbfd5)
+++ protocols/jabber/jabber.h	(revision 5bd21df87b195af211c2280ca00391493a669895)
@@ -208,5 +208,4 @@
 int jabber_buddy_remove( struct im_connection *ic, char *full_jid );
 int jabber_buddy_remove_bare( struct im_connection *ic, char *bare_jid );
-struct groupchat *jabber_chat_by_name( struct im_connection *ic, const char *name );
 time_t jabber_get_timestamp( struct xt_node *xt );
 struct jabber_error *jabber_error_parse( struct xt_node *node, char *xmlns );
@@ -231,4 +230,5 @@
 /* conference.c */
 struct groupchat *jabber_chat_join( struct im_connection *ic, char *room, char *nick, char *password );
+struct groupchat *jabber_chat_by_jid( struct im_connection *ic, const char *name );
 void jabber_chat_free( struct groupchat *c );
 int jabber_chat_msg( struct groupchat *ic, char *message, int flags );
Index: protocols/jabber/jabber_util.c
===================================================================
--- protocols/jabber/jabber_util.c	(revision 4306d8b066d335cb6667414bdd6c5b2e78ccbfd5)
+++ protocols/jabber/jabber_util.c	(revision 5bd21df87b195af211c2280ca00391493a669895)
@@ -614,21 +614,4 @@
 }
 
-struct groupchat *jabber_chat_by_name( struct im_connection *ic, const char *name )
-{
-	char *normalized = jabber_normalize( name );
-	struct groupchat *ret;
-	struct jabber_chat *jc;
-	
-	for( ret = ic->groupchats; ret; ret = ret->next )
-	{
-		jc = ret->data;
-		if( strcmp( normalized, jc->name ) == 0 )
-			break;
-	}
-	g_free( normalized );
-	
-	return ret;
-}
-
 time_t jabber_get_timestamp( struct xt_node *xt )
 {
@@ -682,8 +665,12 @@
 struct jabber_error *jabber_error_parse( struct xt_node *node, char *xmlns )
 {
-	struct jabber_error *err = g_new0( struct jabber_error, 1 );
+	struct jabber_error *err;
 	struct xt_node *c;
 	char *s;
 	
+	if( node == NULL )
+		return NULL;
+	
+	err = g_new0( struct jabber_error, 1 );
 	err->type = xt_find_attr( node, "type" );
 	
Index: protocols/jabber/presence.c
===================================================================
--- protocols/jabber/presence.c	(revision 4306d8b066d335cb6667414bdd6c5b2e78ccbfd5)
+++ protocols/jabber/presence.c	(revision 5bd21df87b195af211c2280ca00391493a669895)
@@ -40,5 +40,5 @@
 	{
 		*s = 0;
-		if( jabber_chat_by_name( ic, from ) )
+		if( jabber_chat_by_jid( ic, from ) )
 			is_chat = 1;
 		*s = '/';
@@ -164,6 +164,8 @@
 	else if( strcmp( type, "error" ) == 0 )
 	{
+		return jabber_cache_handle_packet( ic, node );
+		
+		/*
 		struct jabber_error *err;
-		
 		if( ( c = xt_find_node( node->children, "error" ) ) )
 		{
@@ -173,6 +175,5 @@
 			            err->text ? err->text : "" );
 			jabber_error_free( err );
-		}
-		/* What else to do with it? */
+		} */
 	}
 	
