diff --git a/multiversx_sdk/network_providers/api_network_provider.py b/multiversx_sdk/network_providers/api_network_provider.py index 140fa2db..6cc4940f 100644 --- a/multiversx_sdk/network_providers/api_network_provider.py +++ b/multiversx_sdk/network_providers/api_network_provider.py @@ -16,7 +16,8 @@ ContractQueryRequest from multiversx_sdk.network_providers.contract_query_response import \ ContractQueryResponse -from multiversx_sdk.network_providers.errors import GenericError +from multiversx_sdk.network_providers.errors import (GenericError, + TransactionFetchingError) from multiversx_sdk.network_providers.interface import (IAddress, IContractQuery, IPagination) @@ -129,7 +130,11 @@ def query_contract(self, query: IContractQuery) -> ContractQueryResponse: return ContractQueryResponse.from_http_response(response) def get_transaction(self, tx_hash: str) -> TransactionOnNetwork: - response = self.do_get_generic(f'transactions/{tx_hash}') + try: + response = self.do_get_generic(f'transactions/{tx_hash}') + except GenericError as ge: + raise TransactionFetchingError(ge.url, ge.data) + transaction = TransactionOnNetwork.from_api_http_response(tx_hash, response) return transaction diff --git a/multiversx_sdk/network_providers/api_network_provider_test.py b/multiversx_sdk/network_providers/api_network_provider_test.py index 0dc02eab..b5b59cab 100644 --- a/multiversx_sdk/network_providers/api_network_provider_test.py +++ b/multiversx_sdk/network_providers/api_network_provider_test.py @@ -1,5 +1,4 @@ import base64 -import time import pytest @@ -231,7 +230,6 @@ def test_send_and_await_for_completed_transaction(self): transaction.signature = alice.secret_key.sign(tx_computer.compute_bytes_for_signing(transaction)) hash = self.api.send_transaction(transaction) - time.sleep(1) tx_on_network = self.api.await_transaction_completed(hash) assert tx_on_network.status.is_executed() @@ -250,7 +248,6 @@ def condition(tx: TransactionOnNetwork) -> bool: return tx.status.is_failed() hash = self.api.send_transaction(transaction) - time.sleep(1) tx_on_network = self.api.await_transaction_on_condition( tx_hash=hash, diff --git a/multiversx_sdk/network_providers/errors.py b/multiversx_sdk/network_providers/errors.py index 28644d61..f17af60b 100644 --- a/multiversx_sdk/network_providers/errors.py +++ b/multiversx_sdk/network_providers/errors.py @@ -16,3 +16,8 @@ def __init__(self) -> None: class IsCompletedFieldMissingOnTransaction(Exception): def __init__(self) -> None: super().__init__("The transaction awaiter requires the `is_completed` property to be defined on the transaction object. Perhaps you've used `ProxyNetworkProvider.get_transaction()` and in that case you should also pass `with_process_status=True`") + + +class TransactionFetchingError(Exception): + def __init__(self, url: str, error: Any): + super().__init__(f"Couldn't fetch transaction on url = [{url}], error = [{error}]") diff --git a/multiversx_sdk/network_providers/proxy_network_provider.py b/multiversx_sdk/network_providers/proxy_network_provider.py index 18dba8e5..2f1c5505 100644 --- a/multiversx_sdk/network_providers/proxy_network_provider.py +++ b/multiversx_sdk/network_providers/proxy_network_provider.py @@ -17,7 +17,8 @@ ContractQueryRequest from multiversx_sdk.network_providers.contract_query_response import \ ContractQueryResponse -from multiversx_sdk.network_providers.errors import GenericError +from multiversx_sdk.network_providers.errors import (GenericError, + TransactionFetchingError) from multiversx_sdk.network_providers.interface import IAddress, IContractQuery from multiversx_sdk.network_providers.network_config import NetworkConfig from multiversx_sdk.network_providers.network_status import NetworkStatus @@ -117,10 +118,11 @@ def get_tx() -> Dict[str, Any]: process_status = status_task.result(timeout=5) if status_task else None tx = tx_task.result(timeout=5) + except TimeoutError: raise TimeoutError("Fetching transaction or process status timed out") - except Exception as e: - raise Exception(f"An error occured: {str(e)}") + except GenericError as ge: + raise TransactionFetchingError(ge.url, ge.data) return TransactionOnNetwork.from_proxy_http_response(tx_hash, tx, process_status) diff --git a/multiversx_sdk/network_providers/proxy_network_provider_test.py b/multiversx_sdk/network_providers/proxy_network_provider_test.py index 2f64f0b1..6270beb6 100644 --- a/multiversx_sdk/network_providers/proxy_network_provider_test.py +++ b/multiversx_sdk/network_providers/proxy_network_provider_test.py @@ -1,5 +1,3 @@ -import time - import pytest from multiversx_sdk.core.address import Address @@ -254,7 +252,6 @@ def test_send_and_await_for_completed_transaction(self): transaction.signature = alice.secret_key.sign(tx_computer.compute_bytes_for_signing(transaction)) hash = self.proxy.send_transaction(transaction) - time.sleep(1) tx_on_network = self.proxy.await_transaction_completed(hash) assert tx_on_network.status.is_executed() @@ -273,7 +270,6 @@ def condition(tx: TransactionOnNetwork) -> bool: return tx.status.is_failed() hash = self.proxy.send_transaction(transaction) - time.sleep(1) tx_on_network = self.proxy.await_transaction_on_condition( tx_hash=hash, diff --git a/multiversx_sdk/network_providers/transaction_awaiter.py b/multiversx_sdk/network_providers/transaction_awaiter.py index c3f2ee85..c2d3303e 100644 --- a/multiversx_sdk/network_providers/transaction_awaiter.py +++ b/multiversx_sdk/network_providers/transaction_awaiter.py @@ -1,3 +1,4 @@ +import logging import time from typing import Callable, Optional, Protocol, Union @@ -5,11 +6,14 @@ DEFALT_PATIENCE_IN_MILLISECONDS, DEFAULT_POLLING_INTERVAL_IN_MILLISECONDS, DEFAULT_TIMEOUT_IN_MILLISECONDS) from multiversx_sdk.network_providers.errors import ( - ExpectedTransactionStatusNotReached, IsCompletedFieldMissingOnTransaction) + ExpectedTransactionStatusNotReached, IsCompletedFieldMissingOnTransaction, + TransactionFetchingError) from multiversx_sdk.network_providers.transactions import TransactionOnNetwork ONE_SECOND_IN_MILLISECONDS = 1000 +logger = logging.getLogger("transaction_awaiter") + class ITransactionFetcher(Protocol): def get_transaction(self, tx_hash: str) -> TransactionOnNetwork: @@ -92,6 +96,8 @@ def _await_conditionally(self, if is_condition_satisfied: break + except TransactionFetchingError: + logger.warning("Couldn't fetch transaction. Retrying...") except Exception as ex: raise ex