Commit 252c36c3 authored by Hugo Beauzée-Luyssen's avatar Hugo Beauzée-Luyssen

filesystem: Fix createDirectory usage

It will now check for the folder existence & validity during the
Directory constructor. As such, we need to check for potential
exceptions being thrown, and don't need to check for the return value.
parent 90251f2b
......@@ -43,9 +43,9 @@ namespace factory
virtual ~IFileSystem() = default;
///
/// \brief createDirectory creates a representation of a directory
/// \note This method can't fail. The representation of a directory will be created
/// but subsequent calls to IDirectory methods may fail if the directory
/// doesn't exist, or any other I/O issue occurs
/// \note This method can fail by throwing an exception if the
/// directory doesn't exist, or any other I/O issue occurs.
/// Once created, the path of this IDirectory will be sanitized.
/// \param path An absolute path to a directory
///
virtual std::shared_ptr<fs::IDirectory> createDirectory( const std::string& path ) = 0;
......
......@@ -161,8 +161,16 @@ bool Folder::blacklist( MediaLibraryPtr ml, const std::string& mrl )
auto fsFactory = ml->fsFactoryForMrl( mrl );
if ( fsFactory == nullptr )
return false;
auto folderFs = fsFactory->createDirectory( mrl );
assert( folderFs != nullptr );
std::shared_ptr<fs::IDirectory> folderFs;
try
{
folderFs = fsFactory->createDirectory( mrl );
}
catch ( std::system_error& ex )
{
LOG_ERROR( "Failed to instantiate a directory to ban folder: ", ex.what() );
return false;
}
auto deviceFs = folderFs->device();
if ( deviceFs == nullptr )
{
......@@ -202,8 +210,17 @@ std::shared_ptr<Folder> Folder::fromMrl( MediaLibraryPtr ml, const std::string&
auto fsFactory = ml->fsFactoryForMrl( mrl );
if ( fsFactory == nullptr )
return nullptr;
auto folderFs = fsFactory->createDirectory( mrl );
assert( folderFs != nullptr );
std::shared_ptr<fs::IDirectory> folderFs;
try
{
folderFs = fsFactory->createDirectory( mrl );
}
catch ( const std::system_error& ex )
{
LOG_ERROR( "Failed to instanciate a folder for mrl: ", mrl, ": ", ex.what() );
return nullptr;
}
auto deviceFs = folderFs->device();
if ( deviceFs == nullptr )
{
......
......@@ -73,7 +73,16 @@ bool FsDiscoverer::discover( const std::string& entryPoint )
if ( m_fsFactory->isMrlSupported( entryPoint ) == false )
return false;
std::shared_ptr<fs::IDirectory> fsDir = m_fsFactory->createDirectory( entryPoint );
std::shared_ptr<fs::IDirectory> fsDir;
try
{
fsDir = m_fsFactory->createDirectory( entryPoint );
}
catch ( std::system_error& ex )
{
LOG_WARN( entryPoint, " discovery aborted because of a filesystem error: ", ex.what() );
return true;
}
auto fsDirMrl = fsDir->mrl(); // Saving MRL now since we might need it after fsDir is moved
auto f = Folder::fromMrl( m_ml, fsDirMrl );
// If the folder exists, we assume it will be handled by reload()
......@@ -87,10 +96,6 @@ bool FsDiscoverer::discover( const std::string& entryPoint )
fsDir->files();
return addFolder( std::move( fsDir ), m_probe->getFolderParent().get() );
}
catch ( std::system_error& ex )
{
LOG_WARN( fsDirMrl, " discovery aborted because of a filesystem error: ", ex.what() );
}
catch ( sqlite::errors::ConstraintViolation& ex )
{
LOG_WARN( fsDirMrl, " discovery aborted (assuming blacklisted folder): ", ex.what() );
......@@ -106,18 +111,24 @@ bool FsDiscoverer::discover( const std::string& entryPoint )
void FsDiscoverer::reloadFolder( std::shared_ptr<Folder> f )
{
auto mrl = f->mrl();
auto folder = m_fsFactory->createDirectory( mrl );
assert( folder->device() != nullptr );
if ( folder->device() == nullptr )
return;
try
{
auto folder = m_fsFactory->createDirectory( mrl );
assert( folder->device() != nullptr );
if ( folder->device() == nullptr )
return;
checkFolder( std::move( folder ), std::move( f ), false );
}
catch ( DeviceRemovedException& )
{
LOG_INFO( "Reloading of ", mrl, " was stopped after the device was removed" );
}
catch ( const std::system_error& ex )
{
LOG_INFO( "Failed to instanciate a directory for ", mrl, ": ", ex.what(),
". Can't reload the folder." );
}
}
bool FsDiscoverer::reload()
......
......@@ -34,6 +34,7 @@
#include "Playlist.h"
#include "parser/Task.h"
#include "utils/Filename.h"
#include "utils/Url.h"
namespace medialibrary
{
......@@ -137,9 +138,15 @@ bool Task::restoreLinkedEntities( )
// ie. have we run the MetadataParser service, at least partially
file = File::fetch( m_ml, m_fileId );
parentFolderFs = fsFactory->createDirectory( utils::file::directory( mrl ) );
if ( parentFolderFs == nullptr )
try
{
parentFolderFs = fsFactory->createDirectory( utils::file::directory( mrl ) );
}
catch ( const std::system_error& ex )
{
LOG_ERROR( "Failed to restore task: ", ex.what() );
return false;
}
try
{
......
......@@ -28,6 +28,7 @@
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <system_error>
#include "filesystem/IDirectory.h"
#include "filesystem/IFile.h"
......@@ -165,7 +166,10 @@ struct FileSystemFactory : public factory::IFileSystem
auto d = device( mrl );
if ( d == nullptr )
return std::make_shared<Directory>( "", nullptr );
return d->directory( mrl );
auto dir = d->directory( mrl );
if ( dir == nullptr )
throw std::system_error{ ENOENT, std::generic_category(), "Mock directory" };
return dir;
}
virtual std::shared_ptr<fs::IDevice> createDevice( const std::string& uuid ) override
......@@ -345,7 +349,7 @@ class NoopFsFactory : public factory::IFileSystem
public:
virtual std::shared_ptr<fs::IDirectory> createDirectory( const std::string& ) override
{
return nullptr;
throw std::system_error{ ENOENT, std::generic_category(), "Mock directory" };
}
virtual std::shared_ptr<fs::IDevice> createDevice( const std::string& ) override
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment