diff --git a/lbrynet/core/client/BlobRequester.py b/lbrynet/core/client/BlobRequester.py index 5dd97fc7c..39b214313 100644 --- a/lbrynet/core/client/BlobRequester.py +++ b/lbrynet/core/client/BlobRequester.py @@ -72,6 +72,7 @@ class BlobRequester(object): sent_request = True else: d_r.cancel(InsufficientFundsError()) + d_r.finished_deferred.addErrback(lambda _: True) return defer.fail(InsufficientFundsError()) if sent_request is True: if p_r is not None: diff --git a/lbrynet/core/client/ConnectionManager.py b/lbrynet/core/client/ConnectionManager.py index 990f9a551..683935036 100644 --- a/lbrynet/core/client/ConnectionManager.py +++ b/lbrynet/core/client/ConnectionManager.py @@ -80,13 +80,14 @@ class ConnectionManager(object): return defer.succeed(False) def handle_error(err): - if err.check(InsufficientFundsError): - self.downloader.insufficient_funds() - return False - else: - return err + err.trap(InsufficientFundsError) + self.downloader.insufficient_funds(err) + return False def check_if_request_sent(request_sent, request_creator): + if peer not in self._peer_connections: + # This can happen if the connection is told to close + return False if request_sent is False: if request_creator in self._peer_connections[peer].request_creators: self._peer_connections[peer].request_creators.remove(request_creator) diff --git a/lbrynet/core/client/StandaloneBlobDownloader.py b/lbrynet/core/client/StandaloneBlobDownloader.py index 6fb01888c..082c03f7a 100644 --- a/lbrynet/core/client/StandaloneBlobDownloader.py +++ b/lbrynet/core/client/StandaloneBlobDownloader.py @@ -136,7 +136,10 @@ class StandaloneBlobDownloader(object): def _blob_downloaded(self, blob): self.stop() - self.finished_deferred.callback(blob) + if not self.finished_deferred.called: + self.finished_deferred.callback(blob) - def insufficient_funds(self): - return self.stop() \ No newline at end of file + def insufficient_funds(self, err): + self.stop() + if not self.finished_deferred.called: + self.finished_deferred.errback(err) \ No newline at end of file diff --git a/lbrynet/cryptstream/client/CryptStreamDownloader.py b/lbrynet/cryptstream/client/CryptStreamDownloader.py index b39818ef9..f40f082fe 100644 --- a/lbrynet/cryptstream/client/CryptStreamDownloader.py +++ b/lbrynet/cryptstream/client/CryptStreamDownloader.py @@ -96,7 +96,7 @@ class CryptStreamDownloader(object): d.addCallback(lambda _: set_finished_deferred()) return d - def stop(self): + def stop(self, err=None): def check_if_stop_succeeded(success): self.stopping = False @@ -112,7 +112,7 @@ class CryptStreamDownloader(object): assert self.download_manager is not None self.stopping = True d = self.download_manager.stop_downloading() - self._fire_completed_deferred() + self._fire_completed_deferred(err) d.addCallback(check_if_stop_succeeded) return d @@ -196,10 +196,13 @@ class CryptStreamDownloader(object): self._get_primary_request_creators(download_manager), self._get_secondary_request_creators(download_manager)) - def _fire_completed_deferred(self): + def _fire_completed_deferred(self, err=None): self.finished_deferred, d = None, self.finished_deferred if d is not None: - d.callback(self._get_finished_deferred_callback_value()) + if err is not None: + d.errback(err) + else: + d.callback(self._get_finished_deferred_callback_value()) def _get_finished_deferred_callback_value(self): return None @@ -209,5 +212,5 @@ class CryptStreamDownloader(object): self.completed = True return self.stop() - def insufficient_funds(self): - return self.stop() \ No newline at end of file + def insufficient_funds(self, err): + return self.stop(err=err) \ No newline at end of file diff --git a/lbrynet/interfaces.py b/lbrynet/interfaces.py index de5de679a..ce132e2dc 100644 --- a/lbrynet/interfaces.py +++ b/lbrynet/interfaces.py @@ -521,7 +521,7 @@ class IStreamDownloader(Interface): @rtype: Deferred which fires with anything """ - def insufficient_funds(self): + def insufficient_funds(self, err): """ this function informs the stream downloader that funds are too low to finish downloading. diff --git a/lbrynet/lbryfile/client/LBRYFileDownloader.py b/lbrynet/lbryfile/client/LBRYFileDownloader.py index 3de1a3898..1733ee10b 100644 --- a/lbrynet/lbryfile/client/LBRYFileDownloader.py +++ b/lbrynet/lbryfile/client/LBRYFileDownloader.py @@ -40,9 +40,9 @@ class LBRYFileDownloader(CryptStreamDownloader): else: return defer.succeed(True) - def stop(self): + def stop(self, err=None): d = self._close_output() - d.addCallback(lambda _: CryptStreamDownloader.stop(self)) + d.addCallback(lambda _: CryptStreamDownloader.stop(self, err=err)) return d def _get_progress_manager(self, download_manager): @@ -139,8 +139,8 @@ class LBRYFileSaver(LBRYFileDownloader): d.addCallback(lambda _: set_file_name()) return d - def stop(self): - d = LBRYFileDownloader.stop(self) + def stop(self, err=None): + d = LBRYFileDownloader.stop(self, err=err) d.addCallback(lambda _: self._delete_from_info_manager()) return d @@ -209,8 +209,8 @@ class LBRYFileOpener(LBRYFileDownloader): self.process = None self.process_log = None - def stop(self): - d = LBRYFileDownloader.stop(self) + def stop(self, err=None): + d = LBRYFileDownloader.stop(self, err=err) d.addCallback(lambda _: self._delete_from_info_manager()) return d diff --git a/lbrynet/lbryfilemanager/LBRYFileDownloader.py b/lbrynet/lbryfilemanager/LBRYFileDownloader.py index fa8a093ac..ef52360c2 100644 --- a/lbrynet/lbryfilemanager/LBRYFileDownloader.py +++ b/lbrynet/lbryfilemanager/LBRYFileDownloader.py @@ -43,12 +43,12 @@ class ManagedLBRYFileDownloader(LBRYFileSaver): d.addCallback(restore_status) return d - def stop(self, change_status=True): + def stop(self, err=None, change_status=True): def set_saving_status_done(): self.saving_status = False - d = LBRYFileDownloader.stop(self) # LBRYFileSaver deletes metadata when it's stopped. We don't want that here. + d = LBRYFileDownloader.stop(self, err=err) # LBRYFileSaver deletes metadata when it's stopped. We don't want that here. if change_status is True: self.saving_status = True d.addCallback(lambda _: self._save_status()) diff --git a/lbrynet/lbrynet_console/ControlHandlers.py b/lbrynet/lbrynet_console/ControlHandlers.py index 5276209e4..212295f59 100644 --- a/lbrynet/lbrynet_console/ControlHandlers.py +++ b/lbrynet/lbrynet_console/ControlHandlers.py @@ -6,7 +6,7 @@ from lbrynet.lbryfilemanager.LBRYFileCreator import create_lbry_file from lbrynet.lbryfile.StreamDescriptor import get_sd_info from lbrynet.lbrynet_console.interfaces import IControlHandler, IControlHandlerFactory from lbrynet.core.StreamDescriptor import download_sd_blob -from lbrynet.core.Error import UnknownNameError, InvalidBlobHashError +from lbrynet.core.Error import UnknownNameError, InvalidBlobHashError, InsufficientFundsError from twisted.internet import defer @@ -234,7 +234,7 @@ class AddStream(ControlHandler): prompt_description = None line_prompt = None cancel_prompt = "Trying to locate the stream's metadata. Type \"cancel\" to cancel..." - canceled_message = "Canceled locating the stream descriptor" + canceled_message = "Canceled locating the stream's metadata." line_prompt2 = "Modify options? (y/n)" line_prompt3 = "Start download? (y/n)" @@ -343,7 +343,7 @@ class AddStream(ControlHandler): log.error("An exception occurred attempting to load the stream descriptor: %s", err.getTraceback()) return defer.succeed("An unexpected error occurred attempting to load the stream's metadata.\n" "See console.log for further details.\n\n" - "Press enter to continue" % err.getErrorMessage()) + "Press enter to continue") def _choose_factory(self, info_and_factories): self.loading_info_and_factories_deferred = None @@ -430,8 +430,16 @@ class AddStream(ControlHandler): def _start_download(self): d = self._make_downloader() d.addCallback(lambda stream_downloader: stream_downloader.start()) + d.addErrback(self._handle_download_error) return d + def _handle_download_error(self, err): + if err.check(InsufficientFundsError): + return "Download stopped due to insufficient funds." + else: + log.error("An unexpected error has caused the download to stop: %s" % err.getTraceback()) + return "An unexpected error has caused the download to stop. See console.log for details." + def _make_downloader(self): return self.factory.make_downloader(self.info_validator, self.options_chosen, self.payment_rate_manager) @@ -463,10 +471,13 @@ class AddStreamFromHash(AddStream): return d def _handle_load_failed(self, err): - err.trap(InvalidBlobHashError) self.loading_failed = True - return defer.succeed("The hash you entered is invalid. It must be 96 characters long and " - "contain only hex characters.\n\nPress enter to continue") + if err.check(InvalidBlobHashError): + return defer.succeed("The hash you entered is invalid. It must be 96 characters long and " + "contain only hex characters.\n\nPress enter to continue") + if err.check(InsufficientFundsError): + return defer.succeed("Insufficient funds to download the metadata blob.\n\nPress enter to continue") + return AddStream._handle_load_failed(self, err) class AddStreamFromHashFactory(ControlHandlerFactory): @@ -494,14 +505,14 @@ class AddStreamFromLBRYcrdName(AddStreamFromHash): return d def _handle_load_failed(self, err): - err.trap(UnknownNameError, InvalidBlobHashError) self.loading_failed = True if err.check(UnknownNameError): return defer.succeed("The name %s could not be found.\n\n" "Press enter to continue" % err.getErrorMessage()) - else: + elif err.check(InvalidBlobHashError): return defer.succeed("The metadata for this name is invalid. The stream cannot be downloaded.\n\n" + "Press enter to continue") + return AddStreamFromHash._handle_load_failed(self, err) class AddStreamFromLBRYcrdNameFactory(ControlHandlerFactory): @@ -640,8 +651,16 @@ class ToggleLBRYFileRunning(ControlHandler): def handle_line(self, line): d = self.lbry_file_manager.toggle_lbry_file_running(self.lbry_file.stream_hash) + d.addErrback(self._handle_download_error) return True, d + def _handle_download_error(self, err): + if err.check(InsufficientFundsError): + return "Download stopped due to insufficient funds." + else: + log.error("An unexpected error occurred due to toggling an LBRY file running. %s", err.getTraceback()) + return "An unexpected error occurred. See console.log for details." + class ToggleLBRYFileRunningFactory(LBRYFileChooserFactory): control_handler_class = ToggleLBRYFileRunning diff --git a/lbrynet/lbrynet_console/plugins/BlindRepeater/BlindRepeater.py b/lbrynet/lbrynet_console/plugins/BlindRepeater/BlindRepeater.py index 284114017..4bc9d08f1 100644 --- a/lbrynet/lbrynet_console/plugins/BlindRepeater/BlindRepeater.py +++ b/lbrynet/lbrynet_console/plugins/BlindRepeater/BlindRepeater.py @@ -109,5 +109,5 @@ class BlindRepeater(object): def _update_status(self, stopped=True): self.stopped = stopped - def insufficient_funds(self): + def insufficient_funds(self, err): return self.stop() \ No newline at end of file