updated code base to use generated errors

This commit is contained in:
Lex Berezhny 2019-11-19 13:57:14 -05:00
parent 86617f1bda
commit 57fd3c5801
11 changed files with 503 additions and 203 deletions

View file

@ -1,12 +1,12 @@
Code | Name | Message | Comment
---:|---|---|---
**1xx** | External | **Daemon `start` and other CLI command failures (non-recoverable)**
**10x** | Meta | Meta error codes not presented by `lbrynet` itself but from apps trying to interact with `lbrynet`.
104 | SDKConnectionError | Failed to establish HTTP connection to `lbrynet`. (Is it running?)
105 | SDKRPCUnresponsive | HTTP connection established but daemon is not responding to commands.
106 | SDKWebSocketUnresponsive | Failed to establish WebSocket connection to `lbrynet`. (Is it running?)
107 | SDKWebSocketConnectionError | WebSocket connection established but daemon is not responding to commands.
**11x** | System | Enough of `lbrynet` was able to start to determine external factors causing eventual failure.
**1xx** | Initialization | **Daemon `start` and other CLI command failures (non-recoverable)**
**10x** | Client | Error codes reported by clients connecting to `lbrynet` daemon.
101 | RPCConnection | Failed to establish HTTP connection to `lbrynet`. (Is it running?)
102 | RPCUnresponsive | HTTP connection established but daemon is not responding to commands.
103 | WebSocketConnection | WebSocket connection established but daemon is not responding to commands.
104 | WebSocketUnresponsive | Failed to establish WebSocket connection to `lbrynet`. (Is it running?)
**11x** | Hardware | Enough of `lbrynet` was able to start to determine external factors causing eventual failure.
110 | OutOfSpace | Out of disk space.
111 | OutOfRAM | Out of RAM.
**12x** | Environment | Internal factors preventing `lbrynet` from bootstrapping itself.
@ -53,6 +53,9 @@ Code | Name | Message | Comment
**32x** | ChannelSigning | Channel signing.
320 | ChannelKeyNotFound | Channel signing key not found.
321 | ChannelKeyInvalid | Channel signing key is out of date. | For example, channel was updated but you don't have the updated key.
**33x** | Resolve | Errors while resolving urls.
331 | ResolveError | Failed to resolve '{uri}'.
332 | ResolveTimeout | Failed to resolve '{uri}' within the timeout.
**4xx** | Blob | **Blobs**
**40x** | BlobAvailability | Blob availability.
400 | BlobNotFound | Blob not found.
@ -64,3 +67,19 @@ Code | Name | Message | Comment
411 | CorruptBlob | Blobs is corrupted.
**42x** | BlobEncryption | Encrypting / Creating
420 | BlobFailedEncryption | Failed to encrypt blob.
**43x** | BlobRelated | Exceptions carried over from old error system.
431 | DownloadCancelled | Download was canceled.
432 | DownloadSDTimeout | Failed to download sd blob {download} within timeout.
433 | DownloadDataTimeout | Failed to download data blobs for sd hash {download} within timeout.
434 | InvalidStreamDescriptor | {message}
435 | InvalidData | {message}
436 | InvalidBlobHash | {message}
**5xx** | Component | **Components**
501 | ComponentStartConditionNotMet | Unresolved dependencies for: {components}
502 | ComponentsNotStarted | {message}
**6xx** | CurrencyExchange | **Currency Exchange**
601 | InvalidExchangeRateResponse | Failed to get exchange rate from {source}: {reason}
602 | CurrencyConversion | {message}
603 | InvalidCurrency | Invalid currency: {currency} is not a supported currency.
**7xx** | Purchase | Purchase process errors.
701 | KeyFeeAboveMaxAllowed | {message}

View file

@ -1,202 +1,473 @@
class RPCError(Exception):
code = 0
from .base import BaseError
class PriceDisagreementError(Exception):
pass
class InitializationError(BaseError):
"""
**Daemon `start` and other CLI command failures (non-recoverable)**
"""
class DuplicateStreamHashError(Exception):
pass
class ClientError(InitializationError):
"""
Error codes reported by clients connecting to `lbrynet` daemon.
"""
class DownloadCancelledError(Exception):
pass
class RPCConnectionError(ClientError):
def __init__(self):
super().__init__("Failed to establish HTTP connection to `lbrynet`. (Is it running?)")
class DownloadSDTimeout(Exception):
def __init__(self, download):
super().__init__(f'Failed to download sd blob {download} within timeout')
self.download = download
class RPCUnresponsiveError(ClientError):
def __init__(self):
super().__init__("HTTP connection established but daemon is not responding to commands.")
class DownloadTimeoutError(Exception):
def __init__(self, download):
super().__init__(f'Failed to download {download} within timeout')
self.download = download
class WebSocketConnectionError(ClientError):
def __init__(self):
super().__init__("WebSocket connection established but daemon is not responding to commands.")
class DownloadDataTimeout(Exception):
def __init__(self, download):
super().__init__(f'Failed to download data blobs for sd hash {download} within timeout')
self.download = download
class WebSocketUnresponsiveError(ClientError):
def __init__(self):
super().__init__("Failed to establish WebSocket connection to `lbrynet`. (Is it running?)")
class ResolveTimeout(Exception):
class HardwareError(InitializationError):
"""
Enough of `lbrynet` was able to start to determine external factors causing eventual failure.
"""
class OutOfSpaceError(HardwareError):
def __init__(self):
super().__init__("Out of disk space.")
class OutOfRAMError(HardwareError):
def __init__(self):
super().__init__("Out of RAM.")
class EnvironmentError(InitializationError):
"""
Internal factors preventing `lbrynet` from bootstrapping itself.
"""
class IncompatiblePythonError(EnvironmentError):
def __init__(self):
super().__init__("Incompatible version of Python.")
class IncompatibleDependencyError(EnvironmentError):
def __init__(self):
super().__init__("Incompatible version of some library.")
class ConfigurationError(InitializationError):
"""
Configuration errors.
"""
class CannotWriteConfigurationError(ConfigurationError):
"""
When writing the default config fails on startup, such as due to permission issues.
"""
def __init__(self, path):
super().__init__(f"Cannot write configuration file '{path}'.")
class CannotOpenConfigurationError(ConfigurationError):
"""
Can't open the config file user provided via command line args.
"""
def __init__(self, path):
super().__init__(f"Cannot find provided configuration file '{path}'.")
class CannotParseConfigurationError(ConfigurationError):
"""
Includes the syntax error / line number to help user fix it.
"""
def __init__(self, path):
super().__init__(f"Failed to parse the configuration file '{path}'.")
class ConfigurationMissingError(ConfigurationError):
def __init__(self, path):
super().__init__(f"Configuration file '{path}' is missing setting that has no default / fallback.")
class ConfigurationInvalidError(ConfigurationError):
def __init__(self, path):
super().__init__(f"Configuration file '{path}' has setting with invalid value.")
class CommandError(InitializationError):
"""
Errors preparing to execute commands.
"""
class CommandDoesNotExistError(CommandError):
def __init__(self, command):
super().__init__(f"Command '{command}' does not exist.")
class CommandDeprecatedError(CommandError):
def __init__(self, command):
super().__init__(f"Command '{command}' is deprecated.")
class CommandInvalidArgumentError(CommandError):
def __init__(self, command):
super().__init__(f"Invalid arguments for command '{command}'.")
class CommandTemporarilyUnavailableError(CommandError):
"""
Such as waiting for required components to start.
"""
def __init__(self, command):
super().__init__(f"Command '{command}' is temporarily unavailable.")
class CommandPermanentlyUnavailableError(CommandError):
"""
such as when required component was intentionally configured not to start.
"""
def __init__(self, command):
super().__init__(f"Command '{command}' is permanently unavailable.")
class NetworkingError(BaseError):
"""
**Networking**
"""
class ConnectivityError(NetworkingError):
"""
General connectivity.
"""
class NoInternetError(ConnectivityError):
def __init__(self):
super().__init__("No internet connection.")
class NoUPnPSupportError(ConnectivityError):
def __init__(self):
super().__init__("Router does not support UPnP.")
class WalletConnectivityError(NetworkingError):
"""
Wallet server connectivity.
"""
class WalletConnectionError(WalletConnectivityError):
"""
Should normally not need to be handled higher up as `lbrynet` will retry other servers.
"""
def __init__(self):
super().__init__("Failed connecting to a lbryumx server.")
class WalletConnectionsError(WalletConnectivityError):
"""
Will need to bubble up and require user to do something.
"""
def __init__(self):
super().__init__("Failed connecting to all known lbryumx servers.")
class WalletConnectionDroppedError(WalletConnectivityError):
"""
Maybe we were being bad?
"""
def __init__(self):
super().__init__("lbryumx droppped our connection.")
class WalletDisconnectedError(NetworkingError):
"""
Wallet connection dropped.
"""
class WalletServerSuspiciousError(WalletDisconnectedError):
def __init__(self):
super().__init__("Disconnected from lbryumx server due to suspicious responses. *generic*")
class WalletServerValidationError(WalletDisconnectedError):
def __init__(self):
super().__init__("Disconnected from lbryumx server due to SPV validation failure.")
class WalletServerHeaderError(WalletDisconnectedError):
def __init__(self):
super().__init__("Disconnected from lbryumx server due to incorrect header received.")
class WalletServerVersionError(WalletDisconnectedError):
def __init__(self):
super().__init__("Disconnected from lbryumx server due to incompatible protocol version.")
class WalletServerUnresponsiveError(WalletDisconnectedError):
def __init__(self):
super().__init__("Disconnected from lbryumx server due to unresponsiveness.")
class DataConnectivityError(NetworkingError):
"""
P2P connection errors.
"""
class DataNetworkError(NetworkingError):
"""
P2P download errors.
"""
class DataDownloadError(DataNetworkError):
def __init__(self):
super().__init__("Failed to download blob. *generic*")
class DataUploadError(NetworkingError):
"""
P2P upload errors.
"""
class DHTConnectivityError(NetworkingError):
"""
DHT connectivity issues.
"""
class DHTProtocolError(NetworkingError):
"""
DHT protocol issues.
"""
class BlockchainError(BaseError):
"""
**Blockchain**
"""
class TransactionRejectionError(BlockchainError):
"""
Transaction rejected.
"""
class TransactionRejectedError(TransactionRejectionError):
def __init__(self):
super().__init__("Transaction rejected, unknown reason.")
class TransactionFeeTooLowError(TransactionRejectionError):
def __init__(self):
super().__init__("Fee too low.")
class TransactionInvalidSignatureError(TransactionRejectionError):
def __init__(self):
super().__init__("Invalid signature.")
class InsufficientFundsError(BlockchainError):
"""
determined by wallet prior to attempting to broadcast a tx; this is different for example from a TX
being created and sent but then rejected by lbrycrd for unspendable utxos.
"""
class ChannelSigningError(BlockchainError):
"""
Channel signing.
"""
class ChannelKeyNotFoundError(ChannelSigningError):
def __init__(self):
super().__init__("Channel signing key not found.")
class ChannelKeyInvalidError(ChannelSigningError):
"""
For example, channel was updated but you don't have the updated key.
"""
def __init__(self):
super().__init__("Channel signing key is out of date.")
class ResolveError(BlockchainError):
"""
Errors while resolving urls.
"""
class ResolveErrorError(ResolveError):
def __init__(self, uri):
super().__init__(f'Failed to resolve "{uri}" within the timeout')
self.uri = uri
super().__init__(f"Failed to resolve '{uri}'.")
class RequestCanceledError(Exception):
pass
class ResolveTimeoutError(ResolveError):
def __init__(self, uri):
super().__init__(f"Failed to resolve '{uri}' within the timeout.")
class NegativeFundsError(Exception):
pass
class BlobError(BaseError):
"""
**Blobs**
"""
class NullFundsError(Exception):
pass
class BlobAvailabilityError(BlobError):
"""
Blob availability.
"""
class InsufficientFundsError(RPCError):
code = -310
class BlobNotFoundError(BlobAvailabilityError):
def __init__(self):
super().__init__("Blob not found.")
class CurrencyConversionError(Exception):
pass
class BlobPermissionDeniedError(BlobAvailabilityError):
def __init__(self):
super().__init__("Permission denied to read blob.")
class FileOpenError(ValueError):
# this extends ValueError because it is replacing a ValueError in EncryptedFileDownloader
# and I don't know where it might get caught upstream
pass
class BlobTooBigError(BlobAvailabilityError):
def __init__(self):
super().__init__("Blob is too big.")
class ResolveError(Exception):
pass
class BlobEmptyError(BlobAvailabilityError):
def __init__(self):
super().__init__("Blob is empty.")
class ConnectionClosedBeforeResponseError(Exception):
pass
class BlobDecryptionError(BlobError):
"""
Decryption / Assembly
"""
class KeyFeeAboveMaxAllowed(Exception):
pass
class BlobFailedDecryptionError(BlobDecryptionError):
def __init__(self):
super().__init__("Failed to decrypt blob.")
class InvalidExchangeRateResponse(Exception):
class CorruptBlobError(BlobDecryptionError):
def __init__(self):
super().__init__("Blobs is corrupted.")
class BlobEncryptionError(BlobError):
"""
Encrypting / Creating
"""
class BlobFailedEncryptionError(BlobEncryptionError):
def __init__(self):
super().__init__("Failed to encrypt blob.")
class BlobRelatedError(BlobError):
"""
Exceptions carried over from old error system.
"""
class DownloadCancelledError(BlobRelatedError):
def __init__(self):
super().__init__("Download was canceled.")
class DownloadSDTimeoutError(BlobRelatedError):
def __init__(self, download):
super().__init__(f"Failed to download sd blob {download} within timeout.")
class DownloadDataTimeoutError(BlobRelatedError):
def __init__(self, download):
super().__init__(f"Failed to download data blobs for sd hash {download} within timeout.")
class InvalidStreamDescriptorError(BlobRelatedError):
def __init__(self, message):
super().__init__(f"{message}")
class InvalidDataError(BlobRelatedError):
def __init__(self, message):
super().__init__(f"{message}")
class InvalidBlobHashError(BlobRelatedError):
def __init__(self, message):
super().__init__(f"{message}")
class ComponentError(BaseError):
"""
**Components**
"""
class ComponentStartConditionNotMetError(ComponentError):
def __init__(self, components):
super().__init__(f"Unresolved dependencies for: {components}")
class ComponentsNotStartedError(ComponentError):
def __init__(self, message):
super().__init__(f"{message}")
class CurrencyExchangeError(BaseError):
"""
**Currency Exchange**
"""
class InvalidExchangeRateResponseError(CurrencyExchangeError):
def __init__(self, source, reason):
super().__init__(f'Failed to get exchange rate from {source}:{reason}')
self.source = source
self.reason = reason
super().__init__(f"Failed to get exchange rate from {source}: {reason}")
class UnknownNameError(Exception):
def __init__(self, name):
super().__init__(f'Name {name} is unknown')
self.name = name
class CurrencyConversionError(CurrencyExchangeError):
def __init__(self, message):
super().__init__(f"{message}")
class UnknownClaimID(Exception):
def __init__(self, claim_id):
super().__init__(f'Claim {claim_id} is unknown')
self.claim_id = claim_id
class UnknownURI(Exception):
def __init__(self, uri):
super().__init__(f'URI {uri} cannot be resolved')
self.name = uri
class UnknownOutpoint(Exception):
def __init__(self, outpoint):
super().__init__(f'Outpoint {outpoint} cannot be resolved')
self.outpoint = outpoint
class InvalidName(Exception):
def __init__(self, name, invalid_characters):
self.name = name
self.invalid_characters = invalid_characters
super().__init__(
'URI contains invalid characters: {}'.format(','.join(invalid_characters)))
class UnknownStreamTypeError(Exception):
def __init__(self, stream_type):
self.stream_type = stream_type
def __str__(self):
return repr(self.stream_type)
class InvalidStreamDescriptorError(Exception):
pass
class InvalidStreamInfoError(Exception):
def __init__(self, name, stream_info):
msg = f'{name} has claim with invalid stream info: {stream_info}'
super().__init__(msg)
self.name = name
self.stream_info = stream_info
class MisbehavingPeerError(Exception):
pass
class InvalidDataError(MisbehavingPeerError):
pass
class NoResponseError(MisbehavingPeerError):
pass
class InvalidResponseError(MisbehavingPeerError):
pass
class NoSuchBlobError(Exception):
pass
class NoSuchStreamHash(Exception):
pass
class NoSuchSDHash(Exception):
"""
Raised if sd hash is not known
"""
class InvalidBlobHashError(Exception):
pass
class InvalidHeaderError(Exception):
pass
class InvalidAuthenticationToken(Exception):
pass
class NegotiationError(Exception):
pass
class InvalidCurrencyError(Exception):
class InvalidCurrencyError(CurrencyExchangeError):
def __init__(self, currency):
self.currency = currency
super().__init__(
f'Invalid currency: {currency} is not a supported currency.')
super().__init__(f"Invalid currency: {currency} is not a supported currency.")
class NoSuchDirectoryError(Exception):
def __init__(self, directory):
self.directory = directory
super().__init__(f'No such directory {directory}')
class PurchaseError(BaseError):
"""
Purchase process errors.
"""
class ComponentStartConditionNotMet(Exception):
pass
class KeyFeeAboveMaxAllowedError(PurchaseError):
def __init__(self, message):
super().__init__(f"{message}")
class ComponentsNotStarted(Exception):
pass

View file

@ -1,11 +1,14 @@
import re
from textwrap import fill, indent
CLASS = """
class {name}Error({parent}Error):{doc}
"""
INIT = """\
def __init__({args}):
super().__init__(f'{desc}')
super().__init__({format}"{desc}")
"""
INDENT = ' ' * 4
@ -13,6 +16,7 @@ INDENT = ' ' * 4
def main():
with open('README.md', 'r') as readme:
print('from .base import BaseError\n')
stack = {}
started = False
for line in readme.readlines():
@ -25,19 +29,29 @@ def main():
columns = [c.strip() for c in line.split('|')]
(h, code, desc), comment = columns[:3], ""
if len(columns) == 4:
comment = columns[3]
comment = columns[3].strip()
if h.startswith('**'):
if h.count('x') == 1:
parent = stack[h[2:3]][0]
stack[h.replace('**', '').replace('x', '')] = (code, desc)
else:
parent = stack[h[:2]][0]
if h.count('x') == 2:
stack[h.replace('**', '').replace('x', '')+'0'] = (code, desc)
comment = f'\n{INDENT}"""\n{indent(fill(comment or desc, 100), INDENT)}\n{INDENT}"""'
print(CLASS.format(name=code, parent=parent, doc=comment))
continue
parent = stack[h[:2]][0]
args = ['self']
for arg in re.findall('{([a-z0-1]+)}', desc):
args.append(arg)
fmt = ""
if len(args) > 1:
fmt = "f"
if comment:
comment = f'\n{INDENT}"""\n{INDENT}{comment}\n{INDENT}"""'
print(CLASS.format(name=code, parent=parent, args=', '.join(args), desc=desc, doc=comment))
print((CLASS+INIT).format(
name=code, parent=parent, args=', '.join(args),
desc=desc, doc=comment, format=fmt
))
if __name__ == "__main__":

View file

@ -1,7 +1,7 @@
import logging
import asyncio
from lbry.conf import Config
from lbry.error import ComponentStartConditionNotMet
from lbry.error import ComponentStartConditionNotMetError
from lbry.dht.peer import PeerManager
log = logging.getLogger(__name__)
@ -106,7 +106,7 @@ class ComponentManager:
staged.update(to_stage)
steps.append(step)
elif components:
raise ComponentStartConditionNotMet("Unresolved dependencies for: %s" % components)
raise ComponentStartConditionNotMetError(components)
if reverse:
steps.reverse()
return steps

View file

@ -25,8 +25,7 @@ from lbry.conf import Config, Setting
from lbry.blob.blob_file import is_valid_blobhash, BlobBuffer
from lbry.blob_exchange.downloader import download_blob
from lbry.dht.peer import make_kademlia_peer
from lbry.error import DownloadSDTimeout, ComponentsNotStarted
from lbry.error import NullFundsError, NegativeFundsError, ComponentStartConditionNotMet
from lbry.error import DownloadSDTimeoutError, ComponentsNotStartedError, ComponentStartConditionNotMetError
from lbry.extras import system_info
from lbry.extras.daemon import analytics
from lbry.extras.daemon.Components import WALLET_COMPONENT, DATABASE_COMPONENT, DHT_COMPONENT, BLOB_COMPONENT
@ -68,10 +67,11 @@ def requires(*components, **conditions):
for condition_name in condition_names:
condition_result, err_msg = component_manager.evaluate_condition(condition_name)
if not condition_result:
raise ComponentStartConditionNotMet(err_msg)
raise ComponentStartConditionNotMetError(err_msg)
if not component_manager.all_components_running(*components):
raise ComponentsNotStarted("the following required components have not yet started: "
"%s" % json.dumps(components))
raise ComponentsNotStartedError(
f"the following required components have not yet started: {json.dumps(components)}"
)
return fn(*args, **kwargs)
return _inner
@ -962,7 +962,7 @@ class Daemon(metaclass=JSONRPCServerType):
save_file=save_file, wallet=wallet
)
if not stream:
raise DownloadSDTimeout(uri)
raise DownloadSDTimeoutError(uri)
except Exception as e:
log.warning("Error downloading %s: %s", uri, str(e))
return {"error": str(e)}
@ -1292,10 +1292,6 @@ class Daemon(metaclass=JSONRPCServerType):
accounts = wallet.get_accounts_or_all(funding_account_ids)
amount = self.get_dewies_or_error("amount", amount)
if not amount:
raise NullFundsError
if amount < 0:
raise NegativeFundsError()
if addresses and not isinstance(addresses, list):
addresses = [addresses]

View file

@ -5,7 +5,7 @@ import json
from decimal import Decimal
from typing import Optional
from aiohttp.client_exceptions import ClientError
from lbry.error import InvalidExchangeRateResponse, CurrencyConversionError
from lbry.error import InvalidExchangeRateResponseError, CurrencyConversionError
from lbry.utils import aiohttp_request
from lbry.wallet.dewies import lbc_to_dewies
@ -81,7 +81,7 @@ class MarketFeed:
try:
response = await asyncio.wait_for(self._make_request(), self.REQUESTS_TIMEOUT)
self._save_price(self._subtract_fee(self._handle_response(response)))
except (asyncio.TimeoutError, InvalidExchangeRateResponse, ClientError) as err:
except (asyncio.TimeoutError, InvalidExchangeRateResponseError, ClientError) as err:
self._on_error(err)
await asyncio.sleep(self.EXCHANGE_RATE_UPDATE_RATE_SEC)
@ -108,14 +108,14 @@ class BittrexFeed(MarketFeed):
def _handle_response(self, response):
json_response = json.loads(response)
if 'result' not in json_response:
raise InvalidExchangeRateResponse(self.name, 'result not found')
raise InvalidExchangeRateResponseError(self.name, 'result not found')
trades = json_response['result']
if len(trades) == 0:
raise InvalidExchangeRateResponse(self.market, 'trades not found')
raise InvalidExchangeRateResponseError(self.market, 'trades not found')
totals = sum([i['Total'] for i in trades])
qtys = sum([i['Quantity'] for i in trades])
if totals <= 0 or qtys <= 0:
raise InvalidExchangeRateResponse(self.market, 'quantities were not positive')
raise InvalidExchangeRateResponseError(self.market, 'quantities were not positive')
vwap = totals / qtys
return float(1.0 / vwap)
@ -133,7 +133,7 @@ class LBRYioFeed(MarketFeed):
def _handle_response(self, response):
json_response = json.loads(response)
if 'data' not in json_response:
raise InvalidExchangeRateResponse(self.name, 'result not found')
raise InvalidExchangeRateResponseError(self.name, 'result not found')
return 1.0 / json_response['data']['lbc_btc']
@ -151,9 +151,9 @@ class LBRYioBTCFeed(MarketFeed):
try:
json_response = json.loads(response)
except ValueError:
raise InvalidExchangeRateResponse(self.name, "invalid rate response : %s" % response)
raise InvalidExchangeRateResponseError(self.name, "invalid rate response : %s" % response)
if 'data' not in json_response:
raise InvalidExchangeRateResponse(self.name, 'result not found')
raise InvalidExchangeRateResponseError(self.name, 'result not found')
return 1.0 / json_response['data']['btc_usd']
@ -171,10 +171,10 @@ class CryptonatorBTCFeed(MarketFeed):
try:
json_response = json.loads(response)
except ValueError:
raise InvalidExchangeRateResponse(self.name, "invalid rate response")
raise InvalidExchangeRateResponseError(self.name, "invalid rate response")
if 'ticker' not in json_response or len(json_response['ticker']) == 0 or \
'success' not in json_response or json_response['success'] is not True:
raise InvalidExchangeRateResponse(self.name, 'result not found')
raise InvalidExchangeRateResponseError(self.name, 'result not found')
return float(json_response['ticker']['price'])
@ -192,10 +192,10 @@ class CryptonatorFeed(MarketFeed):
try:
json_response = json.loads(response)
except ValueError:
raise InvalidExchangeRateResponse(self.name, "invalid rate response")
raise InvalidExchangeRateResponseError(self.name, "invalid rate response")
if 'ticker' not in json_response or len(json_response['ticker']) == 0 or \
'success' not in json_response or json_response['success'] is not True:
raise InvalidExchangeRateResponse(self.name, 'result not found')
raise InvalidExchangeRateResponseError(self.name, 'result not found')
return float(json_response['ticker']['price'])

View file

@ -4,7 +4,7 @@ import logging
import binascii
from lbry.dht.peer import make_kademlia_peer
from lbry.error import DownloadSDTimeout
from lbry.error import DownloadSDTimeoutError
from lbry.utils import resolve_host, lru_cache_concurrent
from lbry.stream.descriptor import StreamDescriptor
from lbry.blob_exchange.downloader import BlobDownloader
@ -82,7 +82,7 @@ class StreamDownloader:
log.info("downloaded sd blob %s", self.sd_hash)
self.time_to_descriptor = self.loop.time() - now
except asyncio.TimeoutError:
raise DownloadSDTimeout(self.sd_hash)
raise DownloadSDTimeoutError(self.sd_hash)
# parse the descriptor
self.descriptor = await StreamDescriptor.from_stream_descriptor_blob(

View file

@ -6,7 +6,7 @@ import logging
import binascii
from aiohttp.web import Request, StreamResponse, HTTPRequestRangeNotSatisfiable
from lbry.utils import generate_id
from lbry.error import DownloadSDTimeout
from lbry.error import DownloadSDTimeoutError
from lbry.schema.mime_types import guess_media_type
from lbry.stream.downloader import StreamDownloader
from lbry.stream.descriptor import StreamDescriptor, sanitize_file_name
@ -253,7 +253,7 @@ class ManagedStream:
await asyncio.wait_for(self.downloader.start(node), timeout, loop=self.loop)
except asyncio.TimeoutError:
self._running.clear()
raise DownloadSDTimeout(self.sd_hash)
raise DownloadSDTimeoutError(self.sd_hash)
if self.delayed_stop_task and not self.delayed_stop_task.done():
self.delayed_stop_task.cancel()

View file

@ -7,7 +7,7 @@ import typing
from typing import Optional
from aiohttp.web import Request
from lbry.error import ResolveError, InvalidStreamDescriptorError
from lbry.error import ResolveTimeout, DownloadDataTimeout
from lbry.error import ResolveTimeoutError, DownloadDataTimeoutError
from lbry.utils import cache_concurrent
from lbry.stream.descriptor import StreamDescriptor
from lbry.stream.managed_stream import ManagedStream
@ -371,7 +371,7 @@ class StreamManager:
)
resolved_result = self._convert_to_old_resolve_output(manager, response)
except asyncio.TimeoutError:
raise ResolveTimeout(uri)
raise ResolveTimeoutError(uri)
except Exception as err:
if isinstance(err, asyncio.CancelledError):
raise
@ -437,7 +437,7 @@ class StreamManager:
loop=self.loop)
return stream
except asyncio.TimeoutError:
error = DownloadDataTimeout(stream.sd_hash)
error = DownloadDataTimeoutError(stream.sd_hash)
raise error
except Exception as err: # forgive data timeout, don't delete stream
log.exception("Unexpected error downloading stream:")

View file

@ -9,7 +9,7 @@ from torba.client.basemanager import BaseWalletManager
from torba.client.wallet import ENCRYPT_ON_DISK
from torba.rpc.jsonrpc import CodeMessageError
from lbry.error import KeyFeeAboveMaxAllowed
from lbry.error import KeyFeeAboveMaxAllowedError
from lbry.wallet.dewies import dewies_to_lbc
from lbry.wallet.account import Account
from lbry.wallet.ledger import MainNetLedger
@ -199,7 +199,7 @@ class LbryWalletManager(BaseWalletManager):
error_max_fee = f"{dewies_to_lbc(max_fee_amount)} LBC"
if max_fee['currency'] != 'LBC':
error_max_fee += f" ({max_fee['amount']} {max_fee['currency']})"
raise KeyFeeAboveMaxAllowed(
raise KeyFeeAboveMaxAllowedError(
f"Purchase price of {error_fee} exceeds maximum "
f"configured price of {error_max_fee}."
)

View file

@ -205,12 +205,12 @@ class FileCommands(CommandTestCase):
await self.server.blob_manager.delete_blobs(all_except_sd)
resp = await self.daemon.jsonrpc_get('lbry://foo', timeout=2, save_file=True)
self.assertIn('error', resp)
self.assertEqual('Failed to download data blobs for sd hash %s within timeout' % sd_hash, resp['error'])
self.assertEqual('Failed to download data blobs for sd hash %s within timeout.' % sd_hash, resp['error'])
self.assertTrue(await self.daemon.jsonrpc_file_delete(claim_name='foo'), "data timeout didn't create a file")
await self.server.blob_manager.delete_blobs([sd_hash])
resp = await self.daemon.jsonrpc_get('lbry://foo', timeout=2, save_file=True)
self.assertIn('error', resp)
self.assertEqual('Failed to download sd blob %s within timeout' % sd_hash, resp['error'])
self.assertEqual('Failed to download sd blob %s within timeout.' % sd_hash, resp['error'])
async def wait_files_to_complete(self):
while await self.file_list(status='running'):