diff --git a/program/Source/app/Application.cpp b/program/Source/app/Application.cpp
index d21fc1803631f1bcffcaf6212f94c7954d6375dc..d65e9ac2e5cd21574c9dddd3967aadb7a8f37b75 100644
--- a/program/Source/app/Application.cpp
+++ b/program/Source/app/Application.cpp
@@ -144,9 +144,12 @@ int main(int argc, char **argv) {
 			string fileid;
 			cin >> fileid;
 			FileDescriptor fileDesc = FileDescriptor(fileid);
-			string returned = application.ui.getFile(fileDesc);
-			cout << returned << endl;
-			
+			ReturnableFile returned = application.ui.getFile(fileDesc);
+			if (returned.isValid()) {
+				cout << "Successfully downloaded: " << returned.getLocalFileId() << endl;
+			} else {
+				cout << "ERROR with getting: " << returned.getLocalFileId() << endl << returned.getErrorMessage() << endl;
+			}			
 		}
 		else if (command == "getFileList"){
 			list<FileDescriptor*>* fileTree = application.ui.getFileTree();
diff --git a/program/Source/app/UI.cpp b/program/Source/app/UI.cpp
index d725146faa9f7233ca1ec310d18599885433ce90..91164e912bb1d56b6b810102e5346fe5d1701c26 100644
--- a/program/Source/app/UI.cpp
+++ b/program/Source/app/UI.cpp
@@ -29,7 +29,7 @@ bool UI::createDirectory(string directoryID) {
 }
 
 
-string UI::getFile(FileDescriptor fileDescriptor) {
+ReturnableFile UI::getFile(FileDescriptor fileDescriptor) {
 	LOG_ENTER_EXIT;
 	return app.cfs.getFile(fileDescriptor);
 }
diff --git a/program/Source/app/UI.h b/program/Source/app/UI.h
index 2e1c3be93f5ad20d3e2f0a8cea306847bcc8060d..68e63faadf9cb7584cf2a2148c1c2422fc4440b6 100644
--- a/program/Source/app/UI.h
+++ b/program/Source/app/UI.h
@@ -4,6 +4,7 @@
 #include <string>
 #include <list>
 #include "../fileModel/FileDescriptor.h"
+#include "../fileModel/ReturnableFile.h"
 
 class Application;
 
@@ -47,7 +48,7 @@ public:
 	 * @param fileDescriptor descriptor of the file to get
 	 * @return path to retrieved file
 	 */
-	std::string getFile(FileDescriptor fileDescriptor);
+	ReturnableFile getFile(FileDescriptor fileDescriptor);
 	
 	/**
 	 * It starts the process of deleting a given file from the system
diff --git a/program/Source/dataAccess/Cache.h b/program/Source/dataAccess/Cache.h
index 2b1fac7d22a4a253ed54ec1322e8290e4108532b..9b035e5abf22c4e81e804b96c9b8f36a7bca799a 100644
--- a/program/Source/dataAccess/Cache.h
+++ b/program/Source/dataAccess/Cache.h
@@ -1,6 +1,8 @@
 #ifndef _CACHE_H
 #define _CACHE_H
 
+#include "../fileModel/ReturnableFile.h"
+
 /**
  * Cache class
  * provides interface to the caching functionality
@@ -10,12 +12,12 @@ public:
 	/**
 	 * Tries to get a file from the cache
 	 */
-	virtual void getFile() = 0;
+	virtual ReturnableFile getFile(std::string localFileID) = 0;
 	
 	/**
 	 * Adds a file to the cache
 	 */
-	virtual void addFile() = 0;
+	virtual bool addFile(std::string localFileID) = 0;
 };
 
 #endif //_CACHE_H
\ No newline at end of file
diff --git a/program/Source/dataAccess/CloudFileSystem.cpp b/program/Source/dataAccess/CloudFileSystem.cpp
index af8f40a3ffe03d498954ddfe706fad1ff5974537..3cb0f235dda38c75171b0cbafbfe2a53c5c4cdb2 100644
--- a/program/Source/dataAccess/CloudFileSystem.cpp
+++ b/program/Source/dataAccess/CloudFileSystem.cpp
@@ -77,11 +77,13 @@ bool CloudFileSystem::addFile(string localFileID, string destinationFileID) {
 	
 }
 
-string CloudFileSystem::getFile(FileDescriptor fileDescriptor) {
+ReturnableFile CloudFileSystem::getFile(FileDescriptor fileDescriptor) {
 	LOG_ENTER_EXIT;
 		
 	if (homeNetworkBehaviour == nullptr) {
-		return "No HomeNetworkBehaviour specified";
+		ReturnableFile resultFile(fileDescriptor.getFileID());
+		resultFile.setErrorMessage("No HomeNetworkBehaviour specified");
+		return resultFile;
 	}
 
 	return homeNetworkBehaviour->getFile(fileDescriptor);
diff --git a/program/Source/dataAccess/CloudFileSystem.h b/program/Source/dataAccess/CloudFileSystem.h
index e1152406d1e53a2e0241a7684e286e8c9bc35ac8..7e71b176f4afdf32cc1fc6f6910a1c23d151b51d 100644
--- a/program/Source/dataAccess/CloudFileSystem.h
+++ b/program/Source/dataAccess/CloudFileSystem.h
@@ -106,7 +106,7 @@ public:
 	 * Returns with "" if none is set
 	 * @param fileDescriptor descriptor of the file to be retrieved
 	 */
-	std::string getFile(FileDescriptor fileDescriptor);
+	ReturnableFile getFile(FileDescriptor fileDescriptor);
 	
 	/**
 	 * Creates a directory on the cloud
diff --git a/program/Source/dataAccess/ComputeOnClient.cpp b/program/Source/dataAccess/ComputeOnClient.cpp
index 6cbb7d12494e9e07f348a46552ad68cfa7c634c9..d3a904c896070e19565b8b90179d0cdd7a51813d 100644
--- a/program/Source/dataAccess/ComputeOnClient.cpp
+++ b/program/Source/dataAccess/ComputeOnClient.cpp
@@ -18,7 +18,7 @@ bool ComputeOnClient::addFile(string localFileID, string destinationFileID) {
 	bool success;
 
 	//TODO: well, I guess it needs a parameter... sooner or later.
-	cloudFileSystem.getCache()->addFile();
+	cloudFileSystem.getCache()->addFile(localFileID);
 
 	auto fileDescriptor = Encoder::encode(localFileID, destinationFileID);
 
@@ -38,25 +38,29 @@ bool ComputeOnClient::addFile(string localFileID, string destinationFileID) {
 	return success;
 }
 
-string ComputeOnClient::getFile(FileDescriptor fileDescriptor) {
+ReturnableFile ComputeOnClient::getFile(FileDescriptor fileDescriptor) {
 	LOG_ENTER_EXIT;
 
-	//TODO: check if anything is returned... where does it even return anything?
-	cloudFileSystem.getCache()->getFile();
+	ReturnableFile resultFile = cloudFileSystem.getCache()->getFile(fileDescriptor.getFileID());
 
-	if (cloudFileSystem.findByID(&fileDescriptor) == nullptr){
-		return "Clouds doesn't contain the file.";
-	}
-	FileDescriptor* fileToDownload = cloudFileSystem.findByID(&fileDescriptor);
+	if (!resultFile.isValid()) {
+		if (cloudFileSystem.findByID(&fileDescriptor) == nullptr){
+			resultFile.setErrorMessage("Clouds doesn't contain the file.");
+		}
+		else {
+			FileDescriptor* fileToDownload = cloudFileSystem.findByID(&fileDescriptor);
 
-	if (!cloudFileSystem.isLocked(*fileToDownload))
-	{
-		cloudFileSystem.lock(*fileToDownload);
-		FileDescriptor* downloaded = cloudFileSystem.getCloudAccessLayer()->download(*fileToDownload);
-		cloudFileSystem.unlock(*fileToDownload);
+			if (!cloudFileSystem.isLocked(*fileToDownload))
+			{
+				cloudFileSystem.lock(*fileToDownload);
+				FileDescriptor* downloaded = cloudFileSystem.getCloudAccessLayer()->download(*fileToDownload);
+				cloudFileSystem.unlock(*fileToDownload);
 
-		return Decoder::decode(fileToDownload);
+				return Decoder::decode(fileToDownload);
+			}
+			resultFile.setErrorMessage("File is locked");
+		}
 	}
-	
-	return "File is locked";
+
+	return resultFile;
 }
\ No newline at end of file
diff --git a/program/Source/dataAccess/ComputeOnClient.h b/program/Source/dataAccess/ComputeOnClient.h
index a45d527eda0a5b9a3d278682723a5ab909d1d260..03c363658870d16d33f910e306ce17af41636460 100644
--- a/program/Source/dataAccess/ComputeOnClient.h
+++ b/program/Source/dataAccess/ComputeOnClient.h
@@ -34,7 +34,7 @@ public:
 	 * @param fileDescriptor the descriptor of the file to be retireved
 	 * @return path of the file retrieved
 	 */
-	std::string getFile(FileDescriptor fileDescriptor) override;
+	ReturnableFile getFile(FileDescriptor fileDescriptor) override;
 };
 
 #endif //_COMPUTEONCLIENT_H
\ No newline at end of file
diff --git a/program/Source/dataAccess/ComputeOnPi.cpp b/program/Source/dataAccess/ComputeOnPi.cpp
index e5f54a2b091fc32cda010ecec4cfce0335b3a3f5..e58b19365bf64e0afdfb4e0e50318689f1adda87 100644
--- a/program/Source/dataAccess/ComputeOnPi.cpp
+++ b/program/Source/dataAccess/ComputeOnPi.cpp
@@ -10,7 +10,16 @@ bool ComputeOnPi::addFile(string localFileID, string destinationFileID) {
 	return cloudFileSystem.getHomeNetworkCommunications()->addFileRemote(localFileID);
 }
 
-string ComputeOnPi::getFile(FileDescriptor fileDescriptor) {
+ReturnableFile ComputeOnPi::getFile(FileDescriptor fileDescriptor) {
 	//TODO: change HomeNetworkCommunications' getFileRemote's attribute's type to fileDescriptor
-	return cloudFileSystem.getHomeNetworkCommunications()->getFileRemote(fileDescriptor.getFileID()) ? "File downloaded successfully" : "Could't download file";
+	ReturnableFile resultFile(fileDescriptor.getFileID());
+
+	if (cloudFileSystem.getHomeNetworkCommunications()->getFileRemote(fileDescriptor.getFileID())){
+		resultFile.setValid(true);
+	}
+	else {
+		resultFile.setErrorMessage("Could't download file");
+	}
+
+	return resultFile;
 }
\ No newline at end of file
diff --git a/program/Source/dataAccess/ComputeOnPi.h b/program/Source/dataAccess/ComputeOnPi.h
index 59f1830b4ee5a88d83662c58775ce2de81fd069f..06c25a060961f7966a7b01545c27706bedd44ada 100644
--- a/program/Source/dataAccess/ComputeOnPi.h
+++ b/program/Source/dataAccess/ComputeOnPi.h
@@ -31,7 +31,7 @@ public:
 	 * @param fileDescriptor the descriptor of the file to be retireved
 	 * @return path of the file retrieved
 	 */
-	std::string getFile(FileDescriptor fileDescriptor);
+	ReturnableFile getFile(FileDescriptor fileDescriptor);
 };
 
 #endif //_COMPUTEONPI_H
\ No newline at end of file
diff --git a/program/Source/dataAccess/ConcreteCache.cpp b/program/Source/dataAccess/ConcreteCache.cpp
index 145ab5fda94f19ba615d278dc99794e647e8ce51..a84ef938d596c13d1a7572a3ba31b80cd4883076 100644
--- a/program/Source/dataAccess/ConcreteCache.cpp
+++ b/program/Source/dataAccess/ConcreteCache.cpp
@@ -5,10 +5,13 @@
  * ConcreteCache implementation
  */
 
-void ConcreteCache::getFile() {
+ReturnableFile ConcreteCache::getFile(std::string localFileID) {
 	LOG_ENTER_EXIT;
+	ReturnableFile fileFromCache(localFileID);
+	return fileFromCache;
 }
 
-void ConcreteCache::addFile() {
+bool ConcreteCache::addFile(std::string localFileID) {
 	LOG_ENTER_EXIT;
+	return false;
 }
\ No newline at end of file
diff --git a/program/Source/dataAccess/ConcreteCache.h b/program/Source/dataAccess/ConcreteCache.h
index b13ddb34850328ecbaea86368b7484c6de2b643a..44bc7357388eb2554a99230ede8b626b5c97fb67 100644
--- a/program/Source/dataAccess/ConcreteCache.h
+++ b/program/Source/dataAccess/ConcreteCache.h
@@ -17,12 +17,12 @@ public:
 	/**
 	 * Tries to get a file from the cache
 	 */
-	void getFile();
-	
+	ReturnableFile getFile(std::string localFileID);
+
 	/**
-	 * Adds a file to the cache
-	 */
-	void addFile();
+	* Adds a file to the cache
+	*/
+	bool addFile(std::string localFileID);
 };
 
 #endif //_CONCRETECACHE_H
\ No newline at end of file
diff --git a/program/Source/dataAccess/Decoder.cpp b/program/Source/dataAccess/Decoder.cpp
index 3dffc8e68d1e2c61c68fd65ff1f0a1a68e7b4e45..62912bea00e82e4c4e3cd9bd6a066488534a43aa 100644
--- a/program/Source/dataAccess/Decoder.cpp
+++ b/program/Source/dataAccess/Decoder.cpp
@@ -22,78 +22,78 @@ void Decoder::setFolders(string _dataFolder, string _fragFolder){
 string Decoder::dataFolder = "";
 string Decoder::fragFolder = "";
 
-string Decoder::decode(FileDescriptor* fileDescriptor)
+ReturnableFile Decoder::decode(FileDescriptor* fileDescriptor)
 {
+	ReturnableFile resultFile(fileDescriptor->getFileID());
+
 	if (dataFolder == "" || fragFolder == "") {
-		cout << "Error: folders not set." << endl;
-		return NULL;
-	}
+		resultFile.setErrorMessage("Decoder Error: folders not set.");
+	} 
+	else if (fileDescriptor == nullptr)	{
+		resultFile.setErrorMessage("unable to decode");
+	} else {
+		auto fragments = fileDescriptor->getFragments();
+		if (fragments.size() > 0)
+		{
+			uint32_t max_symbols = 10;
+			uint32_t max_symbol_size = fileDescriptor->getSize() / 10 + 1;
 
-	LOG_ENTER_EXIT;
-	if (fileDescriptor == nullptr)
-	{
-		return "unable to decode";
-	}
+			using file_decoder = kodo::object::file_decoder<
+				kodo::shallow_full_rlnc_decoder<fifi::binary>>;
 
-	auto fragments = fileDescriptor->getFragments();
-	if (fragments.size() > 0)
-	{
-		uint32_t max_symbols = 10;
-		uint32_t max_symbol_size = fileDescriptor->getSize() / 10 + 1;
+			file_decoder::factory decoder_factory(max_symbols, max_symbol_size);
 
-		using file_decoder = kodo::object::file_decoder<
-			kodo::shallow_full_rlnc_decoder<fifi::binary>>;
+			decoder_factory.set_filename(dataFolder + fileDescriptor->getFileID());
+			decoder_factory.set_file_size(fileDescriptor->getSize());
 
-		file_decoder::factory decoder_factory(max_symbols, max_symbol_size);
+			auto decoder = decoder_factory.build();
 
-		decoder_factory.set_filename(dataFolder + fileDescriptor->getFileID());
-		decoder_factory.set_file_size(fileDescriptor->getSize());
+			for (uint32_t i = 0; i < decoder->blocks(); i++)
+			{
+				auto d = decoder->build(i);
 
-		auto decoder = decoder_factory.build();
+				for (int fragNum = 0; fragNum < fragments.size() && !d->is_complete(); fragNum++)
+				{
+					vector<uint8_t> payload;
 
-		for (uint32_t i = 0; i < decoder->blocks(); i++)
-		{
-			auto d = decoder->build(i);
+					ifstream fragFile(
+						fragFolder + fragments[fragNum].getCloudFileID(),
+						ios::in | ios::binary);
 
-			for (int fragNum = 0; fragNum < fragments.size() && !d->is_complete(); fragNum++)
-			{
-				vector<uint8_t> payload;
+					if (!fragFile)
+					{
+						resultFile.setErrorMessage(fragFolder + fragments[fragNum].getCloudFileID().c_str() + ": No such file exists.");
+					}
 
-				ifstream fragFile(
-					fragFolder + fragments[fragNum].getCloudFileID(),
-					ios::in | ios::binary);
+					copy(istreambuf_iterator<char>(fragFile),
+							  istreambuf_iterator<char>(),
+							  back_inserter(payload));
+					fragFile.close();
+					payload.shrink_to_fit();
 
-				if (!fragFile)
-				{
-					throw CloudException("No such file exists");
+					d->decode(payload.data());
 				}
 
-				copy(istreambuf_iterator<char>(fragFile),
-				          istreambuf_iterator<char>(),
-				          back_inserter(payload));
-				fragFile.close();
-				payload.shrink_to_fit();
-
-				d->decode(payload.data());
-			}
+				// Not removed in previous loop, because that doesn't necessarily 
+				// iterate through every fragment
+				for (Fragment fragment : fragments)
+				{
+					remove((fragFolder + fragment.getCloudFileID()).c_str());
+				}
 
-			// Not removed in previous loop, because that doesn't necessarily 
-			// iterate through every fragment
-			for (Fragment fragment : fragments)
-			{
-				remove((fragFolder + fragment.getCloudFileID()).c_str());
+				if (!d->is_complete())
+				{
+					resultFile.setErrorMessage("Error while assembling file");
+				}
 			}
 
-			if (!d->is_complete())
-			{
-				throw CloudException("Error while assembling file");
-			}
+			resultFile.setValid(true);
+		}
+		else
+		{
+			resultFile.setErrorMessage("No fragments found to decode");
 		}
-
-		return "Successfully decoded " + fileDescriptor->getFileID();
-	}
-	else
-	{
-		return "No fragments found to decode";
 	}
+
+	return resultFile;
 }
\ No newline at end of file
diff --git a/program/Source/dataAccess/Decoder.h b/program/Source/dataAccess/Decoder.h
index 712a72ac5e2497ac96686fe051bd2ab955977d7b..d4ec1107773f9847ddd3bddf8a09302f24bdbd3f 100644
--- a/program/Source/dataAccess/Decoder.h
+++ b/program/Source/dataAccess/Decoder.h
@@ -2,6 +2,7 @@
 #define _DECODER_H
 #include <string>
 #include "../fileModel/FileDescriptor.h"
+#include "../fileModel/ReturnableFile.h"
 
 /**
  * Decoder class
@@ -18,7 +19,7 @@ public:
 	 * decodes the fragments to a file 
 	 * @param fileDescriptor descriptor of the file to decode
 	 */
-	static std::string decode(FileDescriptor* fileDescriptor);
+	static ReturnableFile decode(FileDescriptor* fileDescriptor);
 };
 
 #endif //_DECODER_H
\ No newline at end of file
diff --git a/program/Source/dataAccess/HomeNetworkBehaviour.h b/program/Source/dataAccess/HomeNetworkBehaviour.h
index 5801b99860baafe9f0bcce8483dc1ad1c3e3de53..60b8cf69e0cb571393d03154222a5bab7a906377 100644
--- a/program/Source/dataAccess/HomeNetworkBehaviour.h
+++ b/program/Source/dataAccess/HomeNetworkBehaviour.h
@@ -3,6 +3,7 @@
 
 #include <string>
 #include "../fileModel/FileDescriptor.h"
+#include "../fileModel/ReturnableFile.h"
 
 /**
  * HomeNetworkBehaviour class
@@ -26,7 +27,7 @@ public:
 	 * @param fileDescriptor the descriptor of the file to be retireved
 	 * @return path of the file retrieved
 	 */
-	virtual std::string getFile(FileDescriptor fileDescriptor) = 0;
+	virtual ReturnableFile getFile(FileDescriptor fileDescriptor) = 0;
 };
 
 #endif //_HOMENETWORKBEHAVIOUR_H
\ No newline at end of file
diff --git a/program/Source/fileModel/ReturnableFile.cpp b/program/Source/fileModel/ReturnableFile.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..492867f6be393836305ca7aa5d9e867f336138d7
--- /dev/null
+++ b/program/Source/fileModel/ReturnableFile.cpp
@@ -0,0 +1,15 @@
+#include "ReturnableFile.h"
+
+using namespace std;
+
+ReturnableFile::ReturnableFile(string _localFileId)
+{
+	localFileId = _localFileId;
+	valid = false;
+	errorMessage = "";
+}
+
+
+ReturnableFile::~ReturnableFile()
+{
+}
diff --git a/program/Source/fileModel/ReturnableFile.h b/program/Source/fileModel/ReturnableFile.h
new file mode 100644
index 0000000000000000000000000000000000000000..a6774c5be7a4b058a1011058888c78fc3decff54
--- /dev/null
+++ b/program/Source/fileModel/ReturnableFile.h
@@ -0,0 +1,24 @@
+#ifndef _RETURNABLEFILE_H
+#define _RETURNABLEFILE_H
+
+#include <string>
+
+class ReturnableFile
+{
+	std::string localFileId;
+	bool valid;
+	std::string errorMessage;
+public:
+	ReturnableFile(std::string _localFileId);
+	~ReturnableFile();
+
+	std::string getLocalFileId() { return localFileId; }
+	bool isValid() { return valid; }
+	std::string getErrorMessage() { return errorMessage; }
+
+	void setLocalFileId(std::string _localFileId) { localFileId = _localFileId; }
+	void setValid(bool _valid) { valid = _valid; }
+	void setErrorMessage(std::string _errorMessage) { errorMessage = _errorMessage; }
+};
+
+#endif
\ No newline at end of file