From 11705889f1fe66e7fcd7aabd78d8b7a90eb81e5b Mon Sep 17 00:00:00 2001 From: Jonas Kvinge Date: Sun, 28 Dec 2025 20:54:36 +0100 Subject: [PATCH] Show playlist load errors Fixes #1470 --- src/core/songloader.cpp | 12 ++++++++++++ src/core/songloader.h | 1 + src/playlist/songloaderinserter.cpp | 21 ++++++++++++--------- src/playlistparsers/parserbase.cpp | 8 ++++++++ 4 files changed, 33 insertions(+), 9 deletions(-) diff --git a/src/core/songloader.cpp b/src/core/songloader.cpp index bbbef1cbc..eb2891cfb 100644 --- a/src/core/songloader.cpp +++ b/src/core/songloader.cpp @@ -98,6 +98,9 @@ SongLoader::SongLoader(const SharedPtr url_handlers, QObject::connect(timeout_timer_, &QTimer::timeout, this, &SongLoader::Timeout); + QObject::connect(playlist_parser_, &PlaylistParser::Error, this, &SongLoader::ParserError); + QObject::connect(cue_parser_, &CueParser::Error, this, &SongLoader::ParserError); + } SongLoader::~SongLoader() { @@ -106,6 +109,10 @@ SongLoader::~SongLoader() { } +void SongLoader::ParserError(const QString &error) { + errors_ << error; +} + SongLoader::Result SongLoader::Load(const QUrl &url) { if (url.isEmpty()) return Result::Error; @@ -287,6 +294,7 @@ SongLoader::Result SongLoader::LoadLocalAsync(const QString &filename) { } if (parser) { // It's a playlist! + QObject::connect(parser, &ParserBase::Error, this, &SongLoader::ParserError, static_cast(Qt::QueuedConnection | Qt::UniqueConnection)); qLog(Debug) << "Parsing using" << parser->name(); LoadPlaylist(parser, filename); return Result::Success; @@ -706,6 +714,10 @@ void SongLoader::MagicReady() { StopTypefindAsync(true); } + if (parser_) { + QObject::connect(parser_, &ParserBase::Error, this, &SongLoader::ParserError, static_cast(Qt::QueuedConnection | Qt::UniqueConnection)); + } + state_ = State::WaitingForData; if (!IsPipelinePlaying()) { diff --git a/src/core/songloader.h b/src/core/songloader.h index ccc163dcc..7d8236426 100644 --- a/src/core/songloader.h +++ b/src/core/songloader.h @@ -99,6 +99,7 @@ class SongLoader : public QObject { void ScheduleTimeout(); void Timeout(); void StopTypefind(); + void ParserError(const QString &error); #ifdef HAVE_AUDIOCD void AudioCDTracksLoadErrorSlot(const QString &error); diff --git a/src/playlist/songloaderinserter.cpp b/src/playlist/songloaderinserter.cpp index 6c5e2c22c..a1e467faa 100644 --- a/src/playlist/songloaderinserter.cpp +++ b/src/playlist/songloaderinserter.cpp @@ -80,12 +80,13 @@ void SongLoaderInserter::Load(Playlist *destination, const int row, const bool p songs_ << loader->songs(); playlist_name_ = loader->playlist_name(); } - else { - const QStringList errors = loader->errors(); - for (const QString &error : errors) { - Q_EMIT Error(error); - } + + // Always check for errors, even on success (e.g., playlist parsed but some songs failed to load) + const QStringList errors = loader->errors(); + for (const QString &error : errors) { + Q_EMIT Error(error); } + delete loader; } @@ -192,11 +193,13 @@ void SongLoaderInserter::AsyncLoad() { const SongLoader::Result result = loader->LoadFilenamesBlocking(); task_manager_->SetTaskProgress(async_load_id, static_cast(++async_progress)); + // Always check for errors, even on success (e.g., playlist parsed but some songs failed to load) + const QStringList errors = loader->errors(); + for (const QString &error : errors) { + Q_EMIT Error(error); + } + if (result == SongLoader::Result::Error) { - const QStringList errors = loader->errors(); - for (const QString &error : errors) { - Q_EMIT Error(error); - } continue; } diff --git a/src/playlistparsers/parserbase.cpp b/src/playlistparsers/parserbase.cpp index 356d427ab..759b69baf 100644 --- a/src/playlistparsers/parserbase.cpp +++ b/src/playlistparsers/parserbase.cpp @@ -112,10 +112,18 @@ void ParserBase::LoadSong(const QString &filename_or_url, const qint64 beginning } } + // Check if the file exists before trying to read it + if (!QFile::exists(filename)) { + qLog(Error) << "File does not exist:" << filename; + Q_EMIT Error(tr("File %1 does not exist").arg(filename)); + return; + } + if (tagreader_client_) { const TagReaderResult result = tagreader_client_->ReadFileBlocking(filename, song); if (!result.success()) { qLog(Error) << "Could not read file" << filename << result.error_string(); + Q_EMIT Error(tr("Could not read file %1: %2").arg(filename, result.error_string())); } }