diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 8947cc2..bc2756b 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -12,6 +12,15 @@ Added
 * Added option to export all images from scene (File -> Export Images)
 
 
+Fixed
+-----
+
+* Fixed a case where adding/importing an image would hang while
+  reading unsupported exif data (#111)
+* Fixed a hang when saving an open bee file that has been removed
+  since being opened
+
+
 0.3.3 - 2024-05-05
 ==================
 
diff --git a/beeref/fileio/__init__.py b/beeref/fileio/__init__.py
index 4307ca9..5834d97 100644
--- a/beeref/fileio/__init__.py
+++ b/beeref/fileio/__init__.py
@@ -49,7 +49,7 @@ def save_bee(filename, scene, create_new=False, worker=None):
     logger.debug(f'Create new: {create_new}')
     io = SQLiteIO(filename, scene, create_new, worker=worker)
     io.write()
-    logger.info('Saved!')
+    logger.info('End save')
 
 
 def load_images(filenames, pos, scene, worker):
diff --git a/beeref/fileio/sql.py b/beeref/fileio/sql.py
index f4c7b5f..de98686 100644
--- a/beeref/fileio/sql.py
+++ b/beeref/fileio/sql.py
@@ -52,7 +52,7 @@ def handle_sqlite_errors(func):
     def wrapper(self, *args, **kwargs):
         try:
             func(self, *args, **kwargs)
-        except (sqlite3.Error, BeeFileIOError) as e:
+        except Exception as e:
             logger.exception(f'Error while reading/writing {self.filename}')
             try:
                 # Try to roll back transaction if there is any
@@ -80,6 +80,7 @@ def __init__(self, filename, scene, create_new=False, readonly=False,
         self.filename = filename
         self.readonly = readonly
         self.worker = worker
+        self.retry = False
 
     def __del__(self):
         self._close_connection()
@@ -109,7 +110,13 @@ def _establish_connection(self):
         self._connection = sqlite3.connect(uri, uri=True)
         self._cursor = self.connection.cursor()
         if not self.create_new:
-            self._migrate()
+            try:
+                self._migrate()
+            except Exception:
+                # Updating a file failed; try creating it from scratch instead
+                logger.exception('Error migrating bee file')
+                self.create_new = True
+                self._establish_connection()
 
     def _migrate(self):
         """Migrate database if necessary."""
@@ -236,16 +243,19 @@ def read(self):
     def write(self):
         if self.readonly:
             raise sqlite3.OperationalError(
-                'attempt to write a readonly database')
+                'Attempt to write to a readonly database')
         try:
             self.create_schema_on_new()
             self.write_data()
-        except sqlite3.Error:
-            if self.create_new:
-                # If writing to a new file fails, we can't recover
+        except Exception:
+            if self.retry:
+                # Trying to recover failed
                 raise
             else:
-                # Updating a file failed; try creating it from scratch instead
+                self.retry = True
+                # Try creating file from scratch and save again
+                logger.exception(
+                    f'Updating to existing file {self.filename} failed')
                 self.create_new = True
                 self._close_connection()
                 self.write()
diff --git a/tests/fileio/test_sql.py b/tests/fileio/test_sql.py
index 5f640ae..c459dde 100644
--- a/tests/fileio/test_sql.py
+++ b/tests/fileio/test_sql.py
@@ -472,6 +472,7 @@ def test_sqliteio_write_removes_nonexisting_pixmap_item(tmpfile, view):
 
 def test_sqliteio_write_update_recovers_from_borked_file(view, tmpfile):
     item = BeePixmapItem(QtGui.QImage(), filename='bee.png')
+    item.save_id = 1
     view.scene.addItem(item)
 
     with open(tmpfile, 'w') as f:
@@ -483,6 +484,16 @@ def test_sqliteio_write_update_recovers_from_borked_file(view, tmpfile):
     assert result[0] == 1
 
 
+def test_sqliteio_write_update_recovers_from_nonexisting_file(view, tmpfile):
+    item = BeePixmapItem(QtGui.QImage(), filename='bee.png')
+    item.save_id = 1
+    view.scene.addItem(item)
+    io = SQLiteIO(tmpfile, view.scene, create_new=False)
+    io.write()
+    result = io.fetchone('SELECT COUNT(*) FROM items')
+    assert result[0] == 1
+
+
 def test_sqliteio_write_updates_progress(tmpfile, view):
     worker = MagicMock(canceled=False)
     io = SQLiteIO(tmpfile, view.scene, create_new=True, worker=worker)