diff --git a/src/base/bittorrent/bencoderesumedatastorage.cpp b/src/base/bittorrent/bencoderesumedatastorage.cpp index 0fd3a8c75..bf59784e9 100644 --- a/src/base/bittorrent/bencoderesumedatastorage.cpp +++ b/src/base/bittorrent/bencoderesumedatastorage.cpp @@ -338,18 +338,24 @@ void BitTorrent::BencodeResumeDataStorage::Worker::store(const TorrentID &id, co if (torrentInfo) { const QString torrentFilepath = m_resumeDataDir.absoluteFilePath(QString::fromLatin1("%1.torrent").arg(id.toString())); - const lt::create_torrent torrentCreator = lt::create_torrent(*torrentInfo); - const lt::entry metadata = torrentCreator.generate(); try { + const auto torrentCreator = lt::create_torrent(*torrentInfo); + const lt::entry metadata = torrentCreator.generate(); writeEntryToFile(torrentFilepath, metadata); } catch (const RuntimeError &err) { - LogMsg(tr("Couldn't save torrent metadata to '%1'. Error: %2") + LogMsg(tr("Couldn't save torrent metadata to '%1'. Error: %2.") .arg(torrentFilepath, err.message()), Log::CRITICAL); return; } + catch (const std::exception &err) + { + LogMsg(tr("Couldn't save torrent metadata to '%1'. Error: %2.") + .arg(torrentFilepath, QString::fromLocal8Bit(err.what())), Log::CRITICAL); + return; + } } lt::entry data = lt::write_resume_data(p); @@ -371,7 +377,7 @@ void BitTorrent::BencodeResumeDataStorage::Worker::store(const TorrentID &id, co } catch (const RuntimeError &err) { - LogMsg(tr("Couldn't save torrent resume data to '%1'. Error: %2") + LogMsg(tr("Couldn't save torrent resume data to '%1'. Error: %2.") .arg(resumeFilepath, err.message()), Log::CRITICAL); } } diff --git a/src/base/bittorrent/dbresumedatastorage.cpp b/src/base/bittorrent/dbresumedatastorage.cpp index a86b173ef..a745a0af8 100644 --- a/src/base/bittorrent/dbresumedatastorage.cpp +++ b/src/base/bittorrent/dbresumedatastorage.cpp @@ -459,9 +459,18 @@ void BitTorrent::DBResumeDataStorage::Worker::store(const TorrentID &id, const L const std::shared_ptr torrentInfo = std::move(p.ti); if (torrentInfo) { - const lt::create_torrent torrentCreator = lt::create_torrent(*torrentInfo); - const lt::entry metadata = torrentCreator.generate(); - lt::bencode(std::back_inserter(bencodedMetadata), metadata); + try + { + const auto torrentCreator = lt::create_torrent(*torrentInfo); + const lt::entry metadata = torrentCreator.generate(); + lt::bencode(std::back_inserter(bencodedMetadata), metadata); + } + catch (const std::exception &err) + { + LogMsg(tr("Couldn't save torrent metadata. Error: %1.") + .arg(QString::fromLocal8Bit(err.what())), Log::CRITICAL); + return; + } columns.append(DB_COLUMN_METADATA); } diff --git a/src/base/bittorrent/session.cpp b/src/base/bittorrent/session.cpp index 508d6c207..7d91620aa 100644 --- a/src/base/bittorrent/session.cpp +++ b/src/base/bittorrent/session.cpp @@ -2321,7 +2321,7 @@ void Session::exportTorrentFile(const Torrent *torrent, TorrentExportFolder fold } catch (const RuntimeError &err) { - LogMsg(tr("Couldn't export torrent metadata file '%1'. Reason: %2") + LogMsg(tr("Couldn't export torrent metadata file '%1'. Reason: %2.") .arg(newTorrentPath, err.message()), Log::WARNING); } } diff --git a/src/base/bittorrent/torrentcreatorthread.cpp b/src/base/bittorrent/torrentcreatorthread.cpp index 892dd05e9..6e68c0e4b 100644 --- a/src/base/bittorrent/torrentcreatorthread.cpp +++ b/src/base/bittorrent/torrentcreatorthread.cpp @@ -98,6 +98,12 @@ void TorrentCreatorThread::sendProgressSignal(int currentPieceIdx, int totalPiec emit updateProgress(static_cast((currentPieceIdx * 100.) / totalPieces)); } +void TorrentCreatorThread::checkInterruptionRequested() const +{ + if (isInterruptionRequested()) + throw RuntimeError(tr("Operation aborted")); +} + void TorrentCreatorThread::run() { emit updateProgress(0); @@ -118,7 +124,7 @@ void TorrentCreatorThread::run() // need to sort the file names by natural sort order QStringList dirs = {m_params.inputPath}; - QDirIterator dirIter(m_params.inputPath, (QDir::AllDirs | QDir::NoDotAndDotDot), QDirIterator::Subdirectories); + QDirIterator dirIter {m_params.inputPath, (QDir::AllDirs | QDir::NoDotAndDotDot), QDirIterator::Subdirectories}; while (dirIter.hasNext()) { dirIter.next(); @@ -151,7 +157,7 @@ void TorrentCreatorThread::run() fs.add_file(fileName.toStdString(), fileSizeMap[fileName]); } - if (isInterruptionRequested()) return; + checkInterruptionRequested(); #if (LIBTORRENT_VERSION_NUM >= 20000) lt::create_torrent newTorrent {fs, m_params.pieceSize, toNativeTorrentFormatFlag(m_params.torrentFormat)}; @@ -181,9 +187,7 @@ void TorrentCreatorThread::run() lt::set_piece_hashes(newTorrent, Utils::Fs::toNativePath(parentPath).toStdString() , [this, &newTorrent](const lt::piece_index_t n) { - if (isInterruptionRequested()) - throw RuntimeError {tr("Create new torrent aborted.")}; - + checkInterruptionRequested(); sendProgressSignal(static_cast>(n), newTorrent.num_pieces()); }); @@ -194,7 +198,7 @@ void TorrentCreatorThread::run() // Is private ? newTorrent.set_priv(m_params.isPrivate); - if (isInterruptionRequested()) return; + checkInterruptionRequested(); lt::entry entry = newTorrent.generate(); @@ -202,32 +206,30 @@ void TorrentCreatorThread::run() if (!m_params.source.isEmpty()) entry["info"]["source"] = m_params.source.toStdString(); - if (isInterruptionRequested()) return; + checkInterruptionRequested(); // create the torrent QFile outfile {m_params.savePath}; if (!outfile.open(QIODevice::WriteOnly)) - { - throw RuntimeError {tr("Create new torrent file failed. Reason: %1") - .arg(outfile.errorString())}; - } + throw RuntimeError(outfile.errorString()); - if (isInterruptionRequested()) return; + checkInterruptionRequested(); lt::bencode(Utils::IO::FileDeviceOutputIterator {outfile}, entry); if (outfile.error() != QFileDevice::NoError) - { - throw RuntimeError {tr("Create new torrent file failed. Reason: %1") - .arg(outfile.errorString())}; - } + throw RuntimeError(outfile.errorString()); outfile.close(); emit updateProgress(100); emit creationSuccess(m_params.savePath, parentPath); } - catch (const std::exception &e) + catch (const RuntimeError &err) { - emit creationFailure(e.what()); + emit creationFailure(tr("Create new torrent file failed. Reason: %1.").arg(err.message())); + } + catch (const std::exception &err) + { + emit creationFailure(tr("Create new torrent file failed. Reason: %1.").arg(QString::fromLocal8Bit(err.what()))); } } diff --git a/src/base/bittorrent/torrentcreatorthread.h b/src/base/bittorrent/torrentcreatorthread.h index 1a3a6014c..e4280ba97 100644 --- a/src/base/bittorrent/torrentcreatorthread.h +++ b/src/base/bittorrent/torrentcreatorthread.h @@ -65,10 +65,11 @@ namespace BitTorrent class TorrentCreatorThread final : public QThread { Q_OBJECT + Q_DISABLE_COPY_MOVE(TorrentCreatorThread) public: - TorrentCreatorThread(QObject *parent = nullptr); - ~TorrentCreatorThread(); + explicit TorrentCreatorThread(QObject *parent = nullptr); + ~TorrentCreatorThread() override; void create(const TorrentCreatorParams ¶ms); @@ -79,16 +80,15 @@ namespace BitTorrent , const int pieceSize, const bool isAlignmentOptimized, int paddedFileSizeLimit); #endif - protected: - void run() override; - signals: void creationFailure(const QString &msg); void creationSuccess(const QString &path, const QString &branchPath); void updateProgress(int progress); private: + void run() override; void sendProgressSignal(int currentPieceIdx, int totalPieces); + void checkInterruptionRequested() const; TorrentCreatorParams m_params; }; diff --git a/src/base/bittorrent/torrentinfo.cpp b/src/base/bittorrent/torrentinfo.cpp index aaccedac9..00e18de6c 100644 --- a/src/base/bittorrent/torrentinfo.cpp +++ b/src/base/bittorrent/torrentinfo.cpp @@ -167,18 +167,25 @@ TorrentInfo TorrentInfo::loadFromFile(const QString &path, QString *error) noexc void TorrentInfo::saveToFile(const QString &path) const { if (!isValid()) - throw RuntimeError {tr("Invalid metadata.")}; + throw RuntimeError {tr("Invalid metadata")}; - const lt::create_torrent torrentCreator = lt::create_torrent(*(nativeInfo())); - const lt::entry torrentEntry = torrentCreator.generate(); + try + { + const auto torrentCreator = lt::create_torrent(*nativeInfo()); + const lt::entry torrentEntry = torrentCreator.generate(); - QFile torrentFile {path}; - if (!torrentFile.open(QIODevice::WriteOnly)) - throw RuntimeError {torrentFile.errorString()}; + QFile torrentFile {path}; + if (!torrentFile.open(QIODevice::WriteOnly)) + throw RuntimeError(torrentFile.errorString()); - lt::bencode(Utils::IO::FileDeviceOutputIterator {torrentFile}, torrentEntry); - if (torrentFile.error() != QFileDevice::NoError) - throw RuntimeError {torrentFile.errorString()}; + lt::bencode(Utils::IO::FileDeviceOutputIterator {torrentFile}, torrentEntry); + if (torrentFile.error() != QFileDevice::NoError) + throw RuntimeError(torrentFile.errorString()); + } + catch (const lt::system_error &err) + { + throw RuntimeError(QString::fromLocal8Bit(err.what())); + } } bool TorrentInfo::isValid() const diff --git a/src/gui/addnewtorrentdialog.cpp b/src/gui/addnewtorrentdialog.cpp index 4375a9084..0cc29346c 100644 --- a/src/gui/addnewtorrentdialog.cpp +++ b/src/gui/addnewtorrentdialog.cpp @@ -475,7 +475,8 @@ void AddNewTorrentDialog::saveTorrentFile() } catch (const RuntimeError &err) { - QMessageBox::critical(this, tr("I/O Error"), err.message()); + QMessageBox::critical(this, tr("I/O Error") + , tr("Couldn't export torrent metadata file '%1'. Reason: %2.").arg(path, err.message())); } }