From f1d3cadb3b38408b3464f3248edfd65e24d9b190 Mon Sep 17 00:00:00 2001 From: Jonas Kvinge Date: Mon, 9 Aug 2021 23:32:26 +0200 Subject: [PATCH] Add better logging for file open and write errors --- src/collection/collectionwatcher.cpp | 13 +++- src/core/database.cpp | 2 +- src/core/songloader.cpp | 9 ++- src/core/stylesheetloader.cpp | 2 +- src/core/utilities.cpp | 3 + .../albumcoverchoicecontroller.cpp | 20 ++++++- src/covermanager/albumcoverloader.cpp | 59 +++++++++++++------ src/covermanager/currentalbumcoverloader.cpp | 4 +- src/device/devicedatabasebackend.cpp | 5 +- src/device/gpoddevice.cpp | 6 ++ src/main.cpp | 3 + src/moodbar/moodbarloader.cpp | 28 +++++---- src/settings/contextsettingspage.cpp | 3 + src/settings/moodbarsettingspage.cpp | 2 +- src/tidal/tidalstreamurlrequest.cpp | 2 +- 15 files changed, 120 insertions(+), 41 deletions(-) diff --git a/src/collection/collectionwatcher.cpp b/src/collection/collectionwatcher.cpp index df8ab9236..08b436e44 100644 --- a/src/collection/collectionwatcher.cpp +++ b/src/collection/collectionwatcher.cpp @@ -708,7 +708,11 @@ void CollectionWatcher::UpdateCueAssociatedSongs(const QString &file, // Load new CUE songs QFile cue_file(matching_cue); - if (!cue_file.exists() || !cue_file.open(QIODevice::ReadOnly)) return; + if (!cue_file.exists()) return; + if (!cue_file.open(QIODevice::ReadOnly)) { + qLog(Error) << "Could not open CUE file" << matching_cue << "for reading:" << cue_file.errorString(); + return; + } const SongList songs = cue_parser_->Load(&cue_file, matching_cue, path, false); cue_file.close(); @@ -783,7 +787,12 @@ SongList CollectionWatcher::ScanNewFile(const QString &file, const QString &path if (cues_processed->contains(matching_cue)) return songs; QFile cue_file(matching_cue); - if (!cue_file.exists() || !cue_file.open(QIODevice::ReadOnly)) return songs; + if (!cue_file.exists()) return songs; + + if (!cue_file.open(QIODevice::ReadOnly)) { + qLog(Error) << "Could not open CUE file" << matching_cue << "for reading:" << cue_file.errorString(); + return songs; + } // Ignore FILEs pointing to other media files. // Also, watch out for incorrect media files. diff --git a/src/core/database.cpp b/src/core/database.cpp index 665d93d82..ae668a861 100644 --- a/src/core/database.cpp +++ b/src/core/database.cpp @@ -388,7 +388,7 @@ void Database::ExecSchemaCommandsFromFile(QSqlDatabase &db, const QString &filen // Open and read the database schema QFile schema_file(filename); if (!schema_file.open(QIODevice::ReadOnly)) { - qFatal("Couldn't open schema file %s", filename.toUtf8().constData()); + qFatal("Couldn't open schema file %s for reading: %s", filename.toUtf8().constData(), schema_file.errorString().toUtf8().constData()); return; } ExecSchemaCommands(db, QString::fromUtf8(schema_file.readAll()), schema_version, in_transaction); diff --git a/src/core/songloader.cpp b/src/core/songloader.cpp index 37e260ba3..4b2d1fa25 100644 --- a/src/core/songloader.cpp +++ b/src/core/songloader.cpp @@ -281,7 +281,7 @@ SongLoader::Result SongLoader::LoadLocalAsync(const QString &filename) { // It's a local file, so check if it looks like a playlist. Read the first few bytes. QFile file(filename); if (!file.open(QIODevice::ReadOnly)) { - errors_ << tr("Could not open file %1").arg(filename); + errors_ << tr("Could not open file %1 for reading: %2").arg(filename).arg(file.errorString()); return Error; } QByteArray data(file.read(PlaylistParser::kMagicSize)); @@ -312,6 +312,10 @@ SongLoader::Result SongLoader::LoadLocalAsync(const QString &filename) { } return Success; } + else { + errors_ << tr("Could not open CUE file %1 for reading: %2").arg(matching_cue).arg(cue.errorString()); + return Error; + } } // Assume it's just a normal file @@ -364,6 +368,9 @@ void SongLoader::LoadPlaylist(ParserBase *parser, const QString &filename) { songs_ = parser->Load(&file, filename, QFileInfo(filename).path()); file.close(); } + else { + errors_ << tr("Could not open playlist file %1 for reading: %2").arg(filename).arg(file.errorString()); + } } diff --git a/src/core/stylesheetloader.cpp b/src/core/stylesheetloader.cpp index 41db9833b..7628b9d08 100644 --- a/src/core/stylesheetloader.cpp +++ b/src/core/stylesheetloader.cpp @@ -58,7 +58,7 @@ void StyleSheetLoader::SetStyleSheet(QWidget *widget, const QString &filename) { // Load the file QFile file(filename); if (!file.open(QIODevice::ReadOnly)) { - qLog(Error) << "Unable to open" << filename; + qLog(Error) << "Could not open stylesheet file" << filename << "for reading:" << file.errorString(); return; } QTextStream stream(&file); diff --git a/src/core/utilities.cpp b/src/core/utilities.cpp index 138763b62..8745566be 100644 --- a/src/core/utilities.cpp +++ b/src/core/utilities.cpp @@ -939,6 +939,9 @@ QByteArray ReadDataFromFile(const QString &filename) { data = file.readAll(); file.close(); } + else { + qLog(Error) << "Failed to open file" << filename << "for reading:" << file.errorString(); + } return data; } diff --git a/src/covermanager/albumcoverchoicecontroller.cpp b/src/covermanager/albumcoverchoicecontroller.cpp index 04512d7a5..2c32a5820 100644 --- a/src/covermanager/albumcoverchoicecontroller.cpp +++ b/src/covermanager/albumcoverchoicecontroller.cpp @@ -188,6 +188,9 @@ AlbumCoverImageResult AlbumCoverChoiceController::LoadImageFromFile(Song *song) result.cover_url = QUrl::fromLocalFile(cover_file); } } + else { + qLog(Error) << "Failed to open cover file" << cover_file << "for reading:" << file.errorString(); + } return result; @@ -252,9 +255,14 @@ void AlbumCoverChoiceController::SaveCoverToFileManual(const Song &song, const A if (result.is_jpeg() && fileinfo.completeSuffix().compare("jpg", Qt::CaseInsensitive) == 0) { QFile file(save_filename); if (file.open(QIODevice::WriteOnly)) { - file.write(result.image_data); + if (file.write(result.image_data) <= 0) { + qLog(Error) << "Failed writing cover to file" << save_filename << file.errorString(); + } file.close(); } + else { + qLog(Error) << "Failed to open cover file" << save_filename << "for writing:" << file.errorString(); + } } else { result.image.save(save_filename); @@ -596,9 +604,17 @@ QUrl AlbumCoverChoiceController::SaveCoverToFileAutomatic(const Song::Source sou QUrl cover_url; if (result.is_jpeg()) { if (file.open(QIODevice::WriteOnly)) { - if (file.write(result.image_data) > 0) cover_url = QUrl::fromLocalFile(filepath); + if (file.write(result.image_data) > 0) { + cover_url = QUrl::fromLocalFile(filepath); + } + else { + qLog(Error) << "Failed to write cover to file" << file.fileName() << file.errorString(); + } file.close(); } + else { + qLog(Error) << "Failed to open cover file" << file.fileName() << "for writing:" << file.errorString(); + } } else { if (result.image.save(filepath, "JPG")) cover_url = QUrl::fromLocalFile(filepath); diff --git a/src/covermanager/albumcoverloader.cpp b/src/covermanager/albumcoverloader.cpp index 8567c5b1c..4838c0d92 100644 --- a/src/covermanager/albumcoverloader.cpp +++ b/src/covermanager/albumcoverloader.cpp @@ -431,34 +431,47 @@ AlbumCoverLoader::TryLoadResult AlbumCoverLoader::TryLoadImage(Task *task) { if (cover_url.isLocalFile()) { QFile file(cover_url.toLocalFile()); - if (file.exists() && file.open(QIODevice::ReadOnly)) { - QByteArray image_data = file.readAll(); - file.close(); - QImage image; - if (!image_data.isEmpty() && task->options.get_image_ && image.loadFromData(image_data)) { - return TryLoadResult(false, !image.isNull(), type, AlbumCoverImageResult(cover_url, QString(), image_data, image.isNull() ? task->options.default_output_image_ : image)); + if (file.exists()) { + if (file.open(QIODevice::ReadOnly)) { + QByteArray image_data = file.readAll(); + file.close(); + QImage image; + if (!image_data.isEmpty() && task->options.get_image_ && image.loadFromData(image_data)) { + return TryLoadResult(false, !image.isNull(), type, AlbumCoverImageResult(cover_url, QString(), image_data, image.isNull() ? task->options.default_output_image_ : image)); + } + else { + return TryLoadResult(false, !image_data.isEmpty(), type, AlbumCoverImageResult(cover_url, QString(), image_data, image.isNull() ? task->options.default_output_image_ : image)); + } } else { - return TryLoadResult(false, !image_data.isEmpty(), type, AlbumCoverImageResult(cover_url, QString(), image_data, image.isNull() ? task->options.default_output_image_ : image)); + qLog(Error) << "Failed to open cover file" << cover_url << "for reading" << file.errorString(); } } else { - qLog(Error) << "Failed to open album cover file" << cover_url; + qLog(Error) << "Cover file" << cover_url << "does not exist"; } } else if (cover_url.scheme().isEmpty()) { // Assume a local file with no scheme. QFile file(cover_url.path()); - if (file.exists() && file.open(QIODevice::ReadOnly)) { - QByteArray image_data = file.readAll(); - file.close(); - QImage image; - if (!image_data.isEmpty() && task->options.get_image_ && image.loadFromData(image_data)) { - return TryLoadResult(false, !image.isNull(), type, AlbumCoverImageResult(cover_url, QString(), image_data, image.isNull() ? task->options.default_output_image_ : image)); + if (file.exists()) { + if (file.open(QIODevice::ReadOnly)) { + QByteArray image_data = file.readAll(); + file.close(); + QImage image; + if (!image_data.isEmpty() && task->options.get_image_ && image.loadFromData(image_data)) { + return TryLoadResult(false, !image.isNull(), type, AlbumCoverImageResult(cover_url, QString(), image_data, image.isNull() ? task->options.default_output_image_ : image)); + } + else { + return TryLoadResult(false, !image_data.isEmpty(), type, AlbumCoverImageResult(cover_url, QString(), image_data, image.isNull() ? task->options.default_output_image_ : image)); + } } else { - return TryLoadResult(false, !image_data.isEmpty(), type, AlbumCoverImageResult(cover_url, QString(), image_data, image.isNull() ? task->options.default_output_image_ : image)); + qLog(Error) << "Failed to open cover file" << cover_url << "for reading" << file.errorString(); } } + else { + qLog(Error) << "Cover file" << cover_url << "does not exist"; + } } else if (network_->supportedSchemes().contains(cover_url.scheme())) { // Remote URL qLog(Debug) << "Loading remote cover from" << cover_url; @@ -615,7 +628,13 @@ void AlbumCoverLoader::SaveEmbeddedCover(const qint64 id, const QString &song_fi QFile file(cover_filename); - if (file.size() >= 209715200 || !file.open(QIODevice::ReadOnly)) { // Max 200 MB. + if (file.size() >= 209715200) { // Max 200 MB. + emit SaveEmbeddedCoverAsyncFinished(id, false, false); + return; + } + + if (!file.open(QIODevice::ReadOnly)) { + qLog(Error) << "Failed to open cover file" << cover_filename << "for reading:" << file.errorString(); emit SaveEmbeddedCoverAsyncFinished(id, false, false); return; } @@ -656,7 +675,13 @@ void AlbumCoverLoader::SaveEmbeddedCover(const qint64 id, const QList &url QFile file(cover_filename); - if (file.size() >= 209715200 || !file.open(QIODevice::ReadOnly)) { // Max 200 MB. + if (file.size() >= 209715200) { // Max 200 MB. + emit SaveEmbeddedCoverAsyncFinished(id, false, false); + return; + } + + if (!file.open(QIODevice::ReadOnly)) { + qLog(Error) << "Failed to open cover file" << cover_filename << "for reading:" << file.errorString(); emit SaveEmbeddedCoverAsyncFinished(id, false, false); return; } diff --git a/src/covermanager/currentalbumcoverloader.cpp b/src/covermanager/currentalbumcoverloader.cpp index 8c34610f9..c801c4ebf 100644 --- a/src/covermanager/currentalbumcoverloader.cpp +++ b/src/covermanager/currentalbumcoverloader.cpp @@ -86,11 +86,11 @@ void CurrentAlbumCoverLoader::TempAlbumCoverLoaded(const quint64 id, AlbumCoverL result.temp_cover_url = QUrl::fromLocalFile(temp_cover_->fileName()); } else { - qLog(Error) << "Unable to save cover image to" << temp_cover_->fileName(); + qLog(Error) << "Failed to save cover image to" << temp_cover_->fileName() << temp_cover_->errorString(); } } else { - qLog(Error) << "Unable to open" << temp_cover_->fileName(); + qLog(Error) << "Failed to open" << temp_cover_->fileName() << temp_cover_->errorString(); } } diff --git a/src/device/devicedatabasebackend.cpp b/src/device/devicedatabasebackend.cpp index 8a0fec70e..d880a3fb1 100644 --- a/src/device/devicedatabasebackend.cpp +++ b/src/device/devicedatabasebackend.cpp @@ -138,8 +138,9 @@ int DeviceDatabaseBackend::AddDevice(const Device &device) { // Create the songs tables for the device QString filename(":/schema/device-schema.sql"); QFile schema_file(filename); - if (!schema_file.open(QIODevice::ReadOnly)) - qFatal("Couldn't open schema file %s", filename.toUtf8().constData()); + if (!schema_file.open(QIODevice::ReadOnly)) { + qFatal("Couldn't open schema file %s: %s", filename.toUtf8().constData(), schema_file.errorString().toUtf8().constData()); + } QString schema = QString::fromUtf8(schema_file.readAll()); schema.replace("%deviceid", QString::number(id)); diff --git a/src/device/gpoddevice.cpp b/src/device/gpoddevice.cpp index 3b7af52d6..5d603e0b0 100644 --- a/src/device/gpoddevice.cpp +++ b/src/device/gpoddevice.cpp @@ -210,6 +210,12 @@ bool GPodDevice::CopyToStorage(const CopyJob &job) { track->has_artwork = 1; } } + else { + qLog(Error) << "Failed to save" << cover_file->fileName() << cover_file->errorString(); + } + } + else { + qLog(Error) << "Failed to open" << cover_file->fileName() << cover_file->errorString(); } } else if (!job.cover_source_.isEmpty()) { diff --git a/src/main.cpp b/src/main.cpp index 915477084..7594884aa 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -225,6 +225,9 @@ int main(int argc, char *argv[]) { if (file.open(QIODevice::WriteOnly)) { file.close(); } + else { + qLog(Error) << "Could not open settings file" << file.fileName() << "for writing:" << file.errorString(); + } } // Set -rw------- diff --git a/src/moodbar/moodbarloader.cpp b/src/moodbar/moodbarloader.cpp index 2dec2f206..b3f6a985b 100644 --- a/src/moodbar/moodbarloader.cpp +++ b/src/moodbar/moodbarloader.cpp @@ -110,11 +110,16 @@ MoodbarLoader::Result MoodbarLoader::Load(const QUrl &url, QByteArray *data, Moo for (const QString &possible_mood_file : MoodFilenames(filename)) { QFile f(possible_mood_file); - if (f.open(QIODevice::ReadOnly)) { - qLog(Info) << "Loading moodbar data from" << possible_mood_file; - *data = f.readAll(); - f.close(); - return Loaded; + if (f.exists()) { + if (f.open(QIODevice::ReadOnly)) { + qLog(Info) << "Loading moodbar data from" << possible_mood_file; + *data = f.readAll(); + f.close(); + return Loaded; + } + else { + qLog(Error) << "Failed to load moodbar data from" << possible_mood_file << f.errorString(); + } } } @@ -174,8 +179,9 @@ void MoodbarLoader::RequestFinished(MoodbarPipeline *request, const QUrl &url) { QIODevice *cache_file = cache_->prepare(metadata); if (cache_file) { - cache_file->write(request->data()); - cache_->insert(cache_file); + if (cache_file->write(request->data()) > 0) { + cache_->insert(cache_file); + } } // Save the data alongside the original as well if we're configured to. @@ -184,18 +190,18 @@ void MoodbarLoader::RequestFinished(MoodbarPipeline *request, const QUrl &url) { const QString mood_filename(mood_filenames[0]); QFile mood_file(mood_filename); if (mood_file.open(QIODevice::WriteOnly)) { - mood_file.write(request->data()); + if (mood_file.write(request->data()) <= 0) { + qLog(Error) << "Error writing to mood file" << mood_filename << mood_file.errorString(); + } mood_file.close(); - #ifdef Q_OS_WIN32 if (!SetFileAttributes(reinterpret_cast(mood_filename.utf16()), FILE_ATTRIBUTE_HIDDEN)) { qLog(Warning) << "Error setting hidden attribute for file" << mood_filename; } #endif - } else { - qLog(Warning) << "Error opening mood file for writing" << mood_filename; + qLog(Error) << "Error opening mood file" << mood_filename << "for writing:" << mood_file.errorString(); } } } diff --git a/src/settings/contextsettingspage.cpp b/src/settings/contextsettingspage.cpp index da1ebb607..87563a469 100644 --- a/src/settings/contextsettingspage.cpp +++ b/src/settings/contextsettingspage.cpp @@ -122,6 +122,9 @@ ContextSettingsPage::ContextSettingsPage(SettingsDialog *dialog, QWidget *parent ui_->preview_normal->setText(text); file.close(); } + else { + qLog(Error) << "Could not open" << file.fileName() << "for reading:" << file.errorString(); + } } diff --git a/src/settings/moodbarsettingspage.cpp b/src/settings/moodbarsettingspage.cpp index 03110fe14..6a1d5e5f4 100644 --- a/src/settings/moodbarsettingspage.cpp +++ b/src/settings/moodbarsettingspage.cpp @@ -105,7 +105,7 @@ void MoodbarSettingsPage::InitMoodbarPreviews() { // Read the sample data QFile file(":/mood/sample.mood"); if (!file.open(QIODevice::ReadOnly)) { - qLog(Warning) << "Unable to open moodbar sample file"; + qLog(Warning) << "Failed to open moodbar sample file" << file.fileName() << "for reading:" << file.errorString(); return; } QByteArray file_data = file.readAll(); diff --git a/src/tidal/tidalstreamurlrequest.cpp b/src/tidal/tidalstreamurlrequest.cpp index 95e87683b..8af95b13f 100644 --- a/src/tidal/tidalstreamurlrequest.cpp +++ b/src/tidal/tidalstreamurlrequest.cpp @@ -224,7 +224,7 @@ void TidalStreamURLRequest::StreamURLReceived() { file.remove(); } if (!file.open(QIODevice::WriteOnly)) { - Error(QString("Failed to open file %1 for writing.").arg(url.toLocalFile()), json_obj); + Error(QString("Failed to open file %1 for writing: %2.").arg(url.toLocalFile(), file.errorString()), json_obj); emit StreamURLFinished(id_, original_url_, original_url_, Song::FileType_Stream, -1, -1, -1, errors_.first()); return; }