forked from LBRYCommunity/lbry-sdk
file_manager: raise new InvalidStreamURLError
if the URL is invalid
When using `lbrynet get URL`, if the URL is not a valid URL the function `url.URL.parse` will raise a `ValueError` exception which will produce a whole backtrace. For example, this is the case if we provide a channel name with a forward slash but without a stream name. ``` lbrynet get @Non-existing/ ``` ``` Traceback (most recent call last): File "/opt/git/lbry-sdk/lbry/file/file_manager.py", line 84, in download_from_uri if not URL.parse(uri).has_stream: File "/opt/git/lbry-sdk/lbry/schema/url.py", line 114, in parse raise ValueError('Invalid LBRY URL') ValueError: Invalid LBRY URL WARNING lbry.extras.daemon.daemon:1110: Error downloading Non-existing/: Invalid LBRY URL ``` Now we raise a new `InvalidStreamURLError` which can be trapped in the upper functions that use `url.URL.parse` such as `FileManager.download_from_uri`. If we do this the traceback won't be shown. ``` WARNING lbry.file.file_manager:252: Failed to download Non-existing/: Invalid LBRY stream URL: '@Non-existing/' WARNING lbry.extras.daemon.daemon:1110: Error downloading Non-existing/: Invalid LBRY stream URL: '@Non-existing/' ``` This handles the case when trying to download only "channel" parts without the claim part. ``` lbrynet get @Non-existing lbrynet get @Non-existing/ lbrynet get Non-existing/ ```
This commit is contained in:
parent
cdef8b4852
commit
65323b4169
3 changed files with 18 additions and 3 deletions
|
@ -38,6 +38,7 @@ Code | Name | Message
|
||||||
114 | InputStringIsBlank | {argument} cannot be blank.
|
114 | InputStringIsBlank | {argument} cannot be blank.
|
||||||
115 | EmptyPublishedFile | Cannot publish empty file: {file_path}
|
115 | EmptyPublishedFile | Cannot publish empty file: {file_path}
|
||||||
116 | MissingPublishedFile | File does not exist: {file_path}
|
116 | MissingPublishedFile | File does not exist: {file_path}
|
||||||
|
117 | InvalidStreamURL | Invalid LBRY stream URL: '{url}' -- When an URL cannot be downloaded, such as '@Channel/' or a collection
|
||||||
**2xx** | Configuration | Configuration errors.
|
**2xx** | Configuration | Configuration errors.
|
||||||
201 | ConfigWrite | Cannot write configuration file '{path}'. -- When writing the default config fails on startup, such as due to permission issues.
|
201 | ConfigWrite | Cannot write configuration file '{path}'. -- When writing the default config fails on startup, such as due to permission issues.
|
||||||
202 | ConfigRead | Cannot find provided configuration file '{path}'. -- Can't open the config file user provided via command line args.
|
202 | ConfigRead | Cannot find provided configuration file '{path}'. -- Can't open the config file user provided via command line args.
|
||||||
|
|
|
@ -105,6 +105,16 @@ class MissingPublishedFileError(InputValueError):
|
||||||
super().__init__(f"File does not exist: {file_path}")
|
super().__init__(f"File does not exist: {file_path}")
|
||||||
|
|
||||||
|
|
||||||
|
class InvalidStreamURLError(InputValueError):
|
||||||
|
"""
|
||||||
|
When an URL cannot be downloaded, such as '@Channel/' or a collection
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, url):
|
||||||
|
self.url = url
|
||||||
|
super().__init__(f"Invalid LBRY stream URL: '{url}'")
|
||||||
|
|
||||||
|
|
||||||
class ConfigurationError(BaseError):
|
class ConfigurationError(BaseError):
|
||||||
"""
|
"""
|
||||||
Configuration errors.
|
Configuration errors.
|
||||||
|
|
|
@ -5,6 +5,7 @@ from typing import Optional
|
||||||
from aiohttp.web import Request
|
from aiohttp.web import Request
|
||||||
from lbry.error import ResolveError, DownloadSDTimeoutError, InsufficientFundsError
|
from lbry.error import ResolveError, DownloadSDTimeoutError, InsufficientFundsError
|
||||||
from lbry.error import ResolveTimeoutError, DownloadDataTimeoutError, KeyFeeAboveMaxAllowedError
|
from lbry.error import ResolveTimeoutError, DownloadDataTimeoutError, KeyFeeAboveMaxAllowedError
|
||||||
|
from lbry.error import InvalidStreamURLError
|
||||||
from lbry.stream.managed_stream import ManagedStream
|
from lbry.stream.managed_stream import ManagedStream
|
||||||
from lbry.torrent.torrent_manager import TorrentSource
|
from lbry.torrent.torrent_manager import TorrentSource
|
||||||
from lbry.utils import cache_concurrent
|
from lbry.utils import cache_concurrent
|
||||||
|
@ -81,8 +82,11 @@ class FileManager:
|
||||||
payment = None
|
payment = None
|
||||||
try:
|
try:
|
||||||
# resolve the claim
|
# resolve the claim
|
||||||
if not URL.parse(uri).has_stream:
|
try:
|
||||||
raise ResolveError("cannot download a channel claim, specify a /path")
|
if not URL.parse(uri).has_stream:
|
||||||
|
raise InvalidStreamURLError(uri)
|
||||||
|
except ValueError:
|
||||||
|
raise InvalidStreamURLError(uri)
|
||||||
try:
|
try:
|
||||||
resolved_result = await asyncio.wait_for(
|
resolved_result = await asyncio.wait_for(
|
||||||
self.wallet_manager.ledger.resolve(
|
self.wallet_manager.ledger.resolve(
|
||||||
|
@ -244,7 +248,7 @@ class FileManager:
|
||||||
raise error
|
raise error
|
||||||
except Exception as err: # forgive data timeout, don't delete stream
|
except Exception as err: # forgive data timeout, don't delete stream
|
||||||
expected = (DownloadSDTimeoutError, DownloadDataTimeoutError, InsufficientFundsError,
|
expected = (DownloadSDTimeoutError, DownloadDataTimeoutError, InsufficientFundsError,
|
||||||
KeyFeeAboveMaxAllowedError)
|
KeyFeeAboveMaxAllowedError, ResolveError, InvalidStreamURLError)
|
||||||
if isinstance(err, expected):
|
if isinstance(err, expected):
|
||||||
log.warning("Failed to download %s: %s", uri, str(err))
|
log.warning("Failed to download %s: %s", uri, str(err))
|
||||||
elif isinstance(err, asyncio.CancelledError):
|
elif isinstance(err, asyncio.CancelledError):
|
||||||
|
|
Loading…
Reference in a new issue