Commit 7d8aad67 authored by Hugo Beauzée-Luyssen's avatar Hugo Beauzée-Luyssen

IFile/IFolder: throw when accessing an mrl on a removed device

parent 0c63b641
Pipeline #3149 passed with stages
in 12 minutes and 59 seconds
......@@ -48,6 +48,16 @@ public:
virtual ~IFile() = default;
virtual int64_t id() const = 0;
/**
* @brief mrl Returns the full mrl for this file.
* Since we can't compute an mrl for a file or folder that is/was present on
* a removable storage or network share that is not mounted, a
* fs::DeviceRemovedException will be thrown when trying to get the mrl of
* a non present file.
* You should always account for this exception is isRemovable returns true.
* If for some reasons we can't compute the MRL, an empty string will be returned
* @return The folder's mrl
*/
virtual const std::string& mrl() const = 0;
virtual Type type() const = 0;
virtual unsigned int lastModificationDate() const = 0;
......
......@@ -37,10 +37,16 @@ public:
virtual int64_t id() const = 0;
/**
* @brief mrl Returns the full mrl for this folder.
* Caller is responsible for checking isPresent() beforehand, as we
* can't compute an for a folder that is/was present on a removable storage
* or network share that has been unplugged
* If for some reasons we can't compute the MRL, an empty string wil
* Since we can't compute an mrl for a folder that is/was present on a
* removable storage or network share that is not mounted, a
* fs::DeviceRemovedException will be thrown when trying to get the mrl of
* a non present folder.
* Calling isPresent can prevent this to be called with a known missing
* device, but there is always a window between a call to isPresent and mrl()
* in which the device could be removed.
* When calling this function on a removable device, you should check
* for fs::DeviceRemovedException in any case.
* If for some reasons we can't compute the MRL, an empty string will be returned
* @return The folder's mrl
*/
virtual const std::string& mrl() const = 0;
......
......@@ -307,11 +307,7 @@ const std::string& Folder::mrl() const
// When there's no device, we don't know the mountpoint, therefor we don't know the full path
// Calling isPresent will ensure we have the device representation cached locally
if ( isPresent() == false )
{
assert( !"Device isn't present" );
m_fullPath = "";
return m_fullPath;
}
throw fs::DeviceRemovedException();
auto fsFactory = m_ml->fsFactoryForMrl( m_device->scheme() );
if ( fsFactory == nullptr )
......
......@@ -59,7 +59,8 @@ bool CommonDevice::isPresent() const
const std::string& CommonDevice::mountpoint() const
{
assert( m_mountpoints.empty() == false );
if ( m_mountpoints.empty() == true )
throw fs::DeviceRemovedException();
return m_mountpoints[0];
}
......@@ -88,13 +89,15 @@ CommonDevice::matchesMountpoint( const std::string& mrl ) const
std::string CommonDevice::relativeMrl( const std::string& absoluteMrl ) const
{
assert( m_mountpoints.empty() == false );
if ( m_mountpoints.empty() == true )
throw fs::DeviceRemovedException();
return utils::file::removePath( absoluteMrl, m_mountpoints[0] );
}
std::string CommonDevice::absoluteMrl( const std::string& relativeMrl ) const
{
assert( m_mountpoints.empty() == false );
if ( m_mountpoints.empty() == true )
throw fs::DeviceRemovedException();
return m_mountpoints[0] + relativeMrl;
}
......
......@@ -141,24 +141,16 @@ bool ThumbnailerWorker::generateThumbnail( MediaPtr media )
assert( mainFileIt != cend( files ) );
auto file = std::static_pointer_cast<File>( *mainFileIt );
std::string mrl;
// If the file is removable, we need to check if the device is still present
if ( file->isRemovable() == true )
try
{
auto folder = Folder::fetch( m_ml, file->folderId() );
if ( folder == nullptr )
{
assert( !"Failed to get folder associated with file" );
return false;
}
if ( folder->isPresent() == false )
{
LOG_INFO( "Device containing ", media->fileName(), " is missing" );
return false;
}
mrl = file->mrl();
}
else
mrl = file->mrl();
catch ( const fs::DeviceRemovedException& )
{
LOG_WARN( "Aborting file ", file->rawMrl(), " generation due to its "
"containing device being missing" );
return false;
}
LOG_INFO( "Generating ", mrl, " thumbnail..." );
if ( m_generator->generate( media, mrl ) == false )
......
......@@ -216,6 +216,12 @@ void Worker::mainloop()
LOG_INFO( "Done executing ", serviceName, " task on ", task->item().mrl(), " in ",
std::chrono::duration_cast<std::chrono::milliseconds>( duration ).count(), "ms" );
}
catch ( const fs::DeviceRemovedException& )
{
LOG_ERROR( "Parsing of ", task->item().mrl(), " was interrupted "
"due to its containing device being unmounted" );
status = Status::TemporaryUnavailable;
}
catch ( const std::exception& ex )
{
LOG_ERROR( "Caught an exception during ", task->item().mrl(), " [", serviceName, "] parsing: ", ex.what() );
......
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