--- old-misc/rhythmdb/Makefile.am	2006-08-30 23:02:36.000000000 +1000
+++ new-misc/rhythmdb/Makefile.am	2006-08-30 23:02:36.000000000 +1000
@@ -11,6 +11,7 @@
 	-DG_LOG_DOMAIN=\"RhythmDB\"			\
 	-I$(top_srcdir) 				\
 	-I$(top_srcdir)/lib 				\
+	-I$(top_srcdir)/widgets				\
 	-I$(top_srcdir)/metadata			\
 	-I$(top_builddir)/lib                           \
 	$(GDA_CFLAGS)					\

--- old-misc/rhythmdb/rhythmdb-private.h	2006-08-30 23:02:36.000000000 +1000
+++ new-misc/rhythmdb/rhythmdb-private.h	2006-08-30 23:02:36.000000000 +1000
@@ -168,6 +168,7 @@
 	GList *added_entries_to_emit;
 	GList *deleted_entries_to_emit;
 
+	gboolean can_save;
 	gboolean saving;
 	gboolean dirty;
 

--- old-misc/rhythmdb/rhythmdb-tree.h	2006-08-30 23:02:36.000000000 +1000
+++ new-misc/rhythmdb/rhythmdb-tree.h	2006-08-30 23:02:36.000000000 +1000
@@ -42,6 +42,15 @@
 	RHYTHMDB_ENTRY_TREE_LOADING = RHYTHMDB_ENTRY_PRIVATE_FLAG_BASE,
 };
 
+typedef enum
+{
+	RHYTHMDB_TREE_ERROR_DATABASE_TOO_NEW,
+} RhythmTreeDBError;
+
+#define RHYTHMDB_TREE_ERROR (rhythmdb_tree_error_quark ())
+
+GQuark rhythmdb_tree_error_quark (void);
+
 typedef struct
 {
 	RhythmDB parent;

--- old-misc/rhythmdb/rhythmdb.h	2006-08-30 23:02:36.000000000 +1000
+++ new-misc/rhythmdb/rhythmdb.h	2006-08-30 23:02:36.000000000 +1000
@@ -262,7 +263,7 @@
 
 	/* virtual methods */
 
-	void		(*impl_load)		(RhythmDB *db, gboolean *dead);
+	gboolean	(*impl_load)		(RhythmDB *db, gboolean *dead, GError **error);
 	void		(*impl_save)		(RhythmDB *db);
 
 	void		(*impl_entry_new)	(RhythmDB *db, RhythmDBEntry *entry);

--- old-misc/rhythmdb/rhythmdb-tree.c	2006-08-30 23:02:36.000000000 +1000
+++ new-misc/rhythmdb/rhythmdb-tree.c	2006-08-30 23:02:36.000000000 +1000
@@ -63,7 +63,7 @@
 
 static void rhythmdb_tree_finalize (GObject *object);
 
-static void rhythmdb_tree_load (RhythmDB *rdb, gboolean *die);
+static gboolean rhythmdb_tree_load (RhythmDB *rdb, gboolean *die, GError **error);
 static void rhythmdb_tree_save (RhythmDB *rdb);
 static void rhythmdb_tree_entry_new (RhythmDB *db, RhythmDBEntry *entry);
 static void rhythmdb_tree_entry_new_internal (RhythmDB *db, RhythmDBEntry *entry);
@@ -149,6 +149,16 @@
 
 const int RHYTHMDB_TREE_PARSER_INITIAL_BUFFER_SIZE = 512;
 
+GQuark
+rhythmdb_tree_error_quark (void)
+{
+	static GQuark quark;
+	if (!quark)
+		quark = g_quark_from_static_string ("rhythmdb_tree_error");
+
+	return quark;
+}
+
 static void
 rhythmdb_tree_class_init (RhythmDBTreeClass *klass)
 {
@@ -270,6 +280,7 @@
 	GString *buf;
 	RhythmDBPropType propid;
 	gint batch_count;
+	GError **error;
 
 	/* updating */
 	gboolean has_date;
@@ -312,8 +323,12 @@
 					} else if (!strcmp (version, "1.3")) {
 						/* current version*/
 					} else {
-						/* too new. FIXME quit gracefully with error */
-						g_assert_not_reached ();
+						g_set_error (ctx->error,
+							     RHYTHMDB_TREE_ERROR,
+							     RHYTHMDB_TREE_ERROR_DATABASE_TOO_NEW,
+							     _("The database was created by a later version of rhythmbox."
+							       "  This version of rhythmbox cannot read the database."));
+						xmlStopParser (ctx->xmlctx);
 					}
 				} else {
 					g_assert_not_reached ();
@@ -570,9 +585,10 @@
 	}
 }
 
-static void
+static gboolean
 rhythmdb_tree_load (RhythmDB *rdb,
-		    gboolean *die)
+		    gboolean *die,
+		    GError **error)
 {
 	RhythmDBTree *db = RHYTHMDB_TREE (rdb);
 	xmlParserCtxtPtr ctxt;
@@ -591,6 +607,7 @@
 	ctx->db = db;
 	ctx->die = die;
 	ctx->buf = g_string_sized_new (RHYTHMDB_TREE_PARSER_INITIAL_BUFFER_SIZE);
+	ctx->error = error;
 
 	g_object_get (G_OBJECT (db), "name", &name, NULL);
 
@@ -606,13 +623,14 @@
 
 		if (ctx->batch_count)
 			rhythmdb_commit (RHYTHMDB (ctx->db));
-
 	}
 
 	g_string_free (ctx->buf, TRUE);
 	g_free (name);
 	g_free (sax_handler);
 	g_free (ctx);
+
+	return ((*ctx->error) == NULL);
 }
 
 struct RhythmDBTreeSaveContext
--- old-misc/rhythmdb/rhythmdb.c	2006-08-30 23:02:36.000000000 +1000
+++ new-misc/rhythmdb/rhythmdb.c	2006-08-30 23:02:36.000000000 +1000
@@ -45,6 +45,7 @@
 #include "eel-gconf-extensions.h"
 #include "rhythmdb-private.h"
 #include "rhythmdb-property-model.h"
+#include "rb-dialog.h"
 
 #define RB_PARSE_NICK_START (xmlChar *) "["
 #define RB_PARSE_NICK_END (xmlChar *) "]"
@@ -415,6 +416,7 @@
 	db->priv->saving_condition = g_cond_new ();
 	db->priv->saving_mutex = g_mutex_new ();
 
+	db->priv->can_save = TRUE;
 	db->priv->exiting = FALSE;
 	db->priv->saving = FALSE;
 	db->priv->dirty = FALSE;
@@ -2313,15 +2315,36 @@
 	return FALSE;
 }
 
+static gboolean
+rhythmdb_load_error_cb (GError *error)
+{
+	GDK_THREADS_ENTER ();
+	rb_error_dialog (NULL,
+			 _("Could not load the music database"),
+			 error->message);
+	g_error_free (error);
+
+	GDK_THREADS_LEAVE ();
+	return FALSE;
+}
+
 static gpointer
 rhythmdb_load_thread_main (RhythmDB *db)
 {
 	RhythmDBEvent *result;
 	RhythmDBClass *klass = RHYTHMDB_GET_CLASS (db);
+	GError *error = NULL;
 
 	rb_profile_start ("loading db");
 	g_mutex_lock (db->priv->saving_mutex);
-	klass->impl_load (db, &db->priv->exiting);
+	if (klass->impl_load (db, &db->priv->exiting, &error) == FALSE) {
+		rb_debug ("db load failed: disabling saving");
+		db->priv->can_save = FALSE;
+
+		if (error) {
+			g_idle_add ((GSourceFunc) rhythmdb_load_error_cb, error);
+		}
+	}
 	g_mutex_unlock (db->priv->saving_mutex);
 
 	g_object_ref (db);
@@ -2363,7 +2386,7 @@
 
 	g_mutex_lock (db->priv->saving_mutex);
 
-	if (!db->priv->dirty) {
+	if (!db->priv->dirty && !db->priv->can_save) {
 		rb_debug ("no save needed, ignoring");
 		g_mutex_unlock (db->priv->saving_mutex);
 		goto out;
