From 55ddefb0b60d8bccb0b68cdb145393f28a820bd6 Mon Sep 17 00:00:00 2001
From: Travis Ralston <travpc@gmail.com>
Date: Wed, 17 Mar 2021 15:44:17 -0600
Subject: [PATCH] Improve some database handling around downloads

Fixes https://github.com/turt2live/matrix-media-repo/issues/311
---
 CHANGELOG.md                                           |  1 +
 controllers/download_controller/download_controller.go |  8 ++++++++
 controllers/upload_controller/upload_controller.go     | 10 ++++++++++
 storage/datastore/datastore.go                         |  2 ++
 4 files changed, 21 insertions(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index d141fa56..cb853f85 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -24,6 +24,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
 * Fixed a download inefficiency where remote downloads could use extra bandwidth.
 * Fixed a problem where secondary imports can never finish.
 * Fixed imports not handling duplicate media IDs.
+* Fixed some database connection errors not being handled correctly.
 
 ## [1.2.4] - March 5th, 2021
 
diff --git a/controllers/download_controller/download_controller.go b/controllers/download_controller/download_controller.go
index 5727b2b6..d67623ff 100644
--- a/controllers/download_controller/download_controller.go
+++ b/controllers/download_controller/download_controller.go
@@ -182,6 +182,10 @@ func FindMinimalMediaRecord(origin string, mediaId string, downloadRemote bool,
 					ctx.Log.Warn("Media not found")
 					return nil, common.ErrMediaNotFound
 				}
+			} else {
+				// We don't even want to attempt a download - something very wrong happened
+				ctx.Log.Error("Database error trying to get media:", err.Error())
+				return nil, err
 			}
 
 			if !downloadRemote {
@@ -263,6 +267,10 @@ func FindMediaRecord(origin string, mediaId string, downloadRemote bool, ctx rco
 						ctx.Log.Warn("Media not found")
 						return nil, common.ErrMediaNotFound
 					}
+				} else {
+					// We don't even want to attempt a download - something very wrong happened
+					ctx.Log.Error("Database error trying to get media:", err.Error())
+					return nil, err
 				}
 
 				if !downloadRemote {
diff --git a/controllers/upload_controller/upload_controller.go b/controllers/upload_controller/upload_controller.go
index 8dda0699..90060917 100644
--- a/controllers/upload_controller/upload_controller.go
+++ b/controllers/upload_controller/upload_controller.go
@@ -267,6 +267,16 @@ func StoreDirect(f *AlreadyUploadedFile, contents io.ReadCloser, expectedSize in
 			return nil, common.ErrMediaQuarantined
 		}
 
+		// Double check that we're not about to try and store a record we know about
+		for _, knownRecord := range records {
+			if knownRecord.Origin == origin && knownRecord.MediaId == mediaId {
+				ctx.Log.Info("Duplicate media record found - returning unaltered record")
+				ds.DeleteObject(info.Location) // delete temp object
+				trackUploadAsLastAccess(ctx, knownRecord)
+				return knownRecord, nil
+			}
+		}
+
 		media := record
 		media.Origin = origin
 		media.MediaId = mediaId
diff --git a/storage/datastore/datastore.go b/storage/datastore/datastore.go
index e3e6d81b..fb2e709c 100644
--- a/storage/datastore/datastore.go
+++ b/storage/datastore/datastore.go
@@ -113,6 +113,7 @@ func PickDatastore(forKind string, ctx rcontext.RequestContext) (*DatastoreRef,
 
 		ds, err := mediaStore.GetDatastoreByUri(GetUriForDatastore(dsConf))
 		if err != nil {
+			ctx.Log.Error("Error getting datastore: ", err.Error())
 			continue
 		}
 
@@ -121,6 +122,7 @@ func PickDatastore(forKind string, ctx rcontext.RequestContext) (*DatastoreRef,
 		if len(confDatastores) > 1 {
 			size, err = estimatedDatastoreSize(ds, ctx)
 			if err != nil {
+				ctx.Log.Error("Error estimating datastore size for ", ds.DatastoreId, ": ", err.Error())
 				continue
 			}
 		}
-- 
GitLab