Another API exception which should not have been thrown

From the documentation on StorageFolder.TryGetItemAsync(String) Method:

Tries to get the file or folder with the specified name from the current folder. Returns null instead of raising a FileNotFoundException if the specified file or folder is not found.

using IStorageItem = winrt::Windows::Storage::IStorageItem;
IStorageItem EventStorageItem { m_Configuration.m_ApplicationStorageFolder.TryGetItemAsync(m_FileName).get() };

Exception thrown at 0x00007FFB06BDA799 (KernelBase.dll) in DownloadIssue.exe: WinRT originate error – 0x80070002 : ‘An item cannot be found with the specified name (Issue-1714684927.tsv).’.

It looks like TryGetItemAsync is a wrapper over GetItemAsync to suppress exception if file is not found, and it should be the other way around: if there is no file, there is nullptr result with no exception. In conjunction with missing mode equivalent to OPEN_ALWAYS it makes it not really convenient to write code free from exceptions.

Exceptionless workaround via file query:

#if 1
	using namespace winrt::Windows::Storage;
	StorageFile EventStorageFile(nullptr);
	Search::StorageFileQueryResult const FileQueryResult { m_Configuration.m_ApplicationStorageFolder.CreateFileQuery() };
	auto const FileVector { FileQueryResult.GetFilesAsync().get() };
	for(auto FileVectorIterator { FileVector.First() }; FileVectorIterator.HasCurrent(); FileVectorIterator.MoveNext())
		auto const StorageFile { FileVectorIterator.Current() };
		if(StorageFile.IsOfType(StorageItemTypes::File) && _wcsicmp(StorageFile.Name().c_str(), m_FileName.c_str()) == 0)
			EventStorageFile = StorageFile;
	// TODO: Get rid of exception if file is missing
	IStorageItem EventStorageItem { m_Configuration.m_ApplicationStorageFolder.TryGetItemAsync(m_FileName).get() };
	StorageFile EventStorageFile {<StorageFile>() };

Leave a Reply