Fix bug when fetching orders fails
This commit is contained in:
parent
6362bfc36e
commit
c6124180fe
@ -37,6 +37,13 @@ class InvalidOrderException(FreqtradeException):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class RetryableOrderError(InvalidOrderException):
|
||||||
|
"""
|
||||||
|
This is returned when the order is not found.
|
||||||
|
This Error will be repeated with increasing backof (in line with DDosError).
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
class ExchangeError(DependencyException):
|
class ExchangeError(DependencyException):
|
||||||
"""
|
"""
|
||||||
Error raised out of the exchange.
|
Error raised out of the exchange.
|
||||||
|
@ -3,7 +3,8 @@ import logging
|
|||||||
import time
|
import time
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
|
|
||||||
from freqtrade.exceptions import DDosProtection, TemporaryError
|
from freqtrade.exceptions import (DDosProtection, RetryableOrderError,
|
||||||
|
TemporaryError)
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -109,8 +110,8 @@ def retrier_async(f):
|
|||||||
count -= 1
|
count -= 1
|
||||||
kwargs.update({'count': count})
|
kwargs.update({'count': count})
|
||||||
logger.warning('retrying %s() still for %s times', f.__name__, count)
|
logger.warning('retrying %s() still for %s times', f.__name__, count)
|
||||||
if isinstance(ex, DDosProtection):
|
if isinstance(ex, DDosProtection) or isinstance(ex, RetryableOrderError):
|
||||||
await asyncio.sleep(1)
|
await asyncio.sleep(calculate_backoff(count + 1, API_RETRY_COUNT))
|
||||||
return await wrapper(*args, **kwargs)
|
return await wrapper(*args, **kwargs)
|
||||||
else:
|
else:
|
||||||
logger.warning('Giving up retrying: %s()', f.__name__)
|
logger.warning('Giving up retrying: %s()', f.__name__)
|
||||||
@ -125,14 +126,15 @@ def retrier(_func=None, retries=API_RETRY_COUNT):
|
|||||||
count = kwargs.pop('count', retries)
|
count = kwargs.pop('count', retries)
|
||||||
try:
|
try:
|
||||||
return f(*args, **kwargs)
|
return f(*args, **kwargs)
|
||||||
except TemporaryError as ex:
|
except (TemporaryError, RetryableOrderError) as ex:
|
||||||
logger.warning('%s() returned exception: "%s"', f.__name__, ex)
|
logger.warning('%s() returned exception: "%s"', f.__name__, ex)
|
||||||
if count > 0:
|
if count > 0:
|
||||||
count -= 1
|
count -= 1
|
||||||
kwargs.update({'count': count})
|
kwargs.update({'count': count})
|
||||||
logger.warning('retrying %s() still for %s times', f.__name__, count)
|
logger.warning('retrying %s() still for %s times', f.__name__, count)
|
||||||
if isinstance(ex, DDosProtection):
|
if isinstance(ex, DDosProtection) or isinstance(ex, RetryableOrderError):
|
||||||
time.sleep(calculate_backoff(count, retries))
|
# increasing backoff
|
||||||
|
time.sleep(calculate_backoff(count + 1, retries))
|
||||||
return wrapper(*args, **kwargs)
|
return wrapper(*args, **kwargs)
|
||||||
else:
|
else:
|
||||||
logger.warning('Giving up retrying: %s()', f.__name__)
|
logger.warning('Giving up retrying: %s()', f.__name__)
|
||||||
|
@ -22,7 +22,7 @@ from freqtrade.constants import ListPairsWithTimeframes
|
|||||||
from freqtrade.data.converter import ohlcv_to_dataframe, trades_dict_to_list
|
from freqtrade.data.converter import ohlcv_to_dataframe, trades_dict_to_list
|
||||||
from freqtrade.exceptions import (DDosProtection, ExchangeError,
|
from freqtrade.exceptions import (DDosProtection, ExchangeError,
|
||||||
InvalidOrderException, OperationalException,
|
InvalidOrderException, OperationalException,
|
||||||
TemporaryError)
|
RetryableOrderError, TemporaryError)
|
||||||
from freqtrade.exchange.common import BAD_EXCHANGES, retrier, retrier_async
|
from freqtrade.exchange.common import BAD_EXCHANGES, retrier, retrier_async
|
||||||
from freqtrade.misc import deep_merge_dicts, safe_value_fallback
|
from freqtrade.misc import deep_merge_dicts, safe_value_fallback
|
||||||
|
|
||||||
@ -1015,6 +1015,9 @@ class Exchange:
|
|||||||
f'Tried to get an invalid dry-run-order (id: {order_id}). Message: {e}') from e
|
f'Tried to get an invalid dry-run-order (id: {order_id}). Message: {e}') from e
|
||||||
try:
|
try:
|
||||||
return self._api.fetch_order(order_id, pair)
|
return self._api.fetch_order(order_id, pair)
|
||||||
|
except ccxt.OrderNotFound as e:
|
||||||
|
raise RetryableOrderError(
|
||||||
|
f'Order not found (id: {order_id}). Message: {e}') from e
|
||||||
except ccxt.InvalidOrder as e:
|
except ccxt.InvalidOrder as e:
|
||||||
raise InvalidOrderException(
|
raise InvalidOrderException(
|
||||||
f'Tried to get an invalid order (id: {order_id}). Message: {e}') from e
|
f'Tried to get an invalid order (id: {order_id}). Message: {e}') from e
|
||||||
|
@ -1888,6 +1888,18 @@ def test_fetch_order(default_conf, mocker, exchange_name):
|
|||||||
exchange.fetch_order(order_id='_', pair='TKN/BTC')
|
exchange.fetch_order(order_id='_', pair='TKN/BTC')
|
||||||
assert api_mock.fetch_order.call_count == 1
|
assert api_mock.fetch_order.call_count == 1
|
||||||
|
|
||||||
|
api_mock.fetch_order = MagicMock(side_effect=ccxt.OrderNotFound("Order not found"))
|
||||||
|
exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name)
|
||||||
|
with patch('freqtrade.exchange.common.time.sleep') as tm:
|
||||||
|
with pytest.raises(InvalidOrderException):
|
||||||
|
exchange.fetch_order(order_id='_', pair='TKN/BTC')
|
||||||
|
# Ensure backoff is called
|
||||||
|
assert tm.call_args_list[0][0][0] == 1
|
||||||
|
assert tm.call_args_list[1][0][0] == 2
|
||||||
|
assert tm.call_args_list[2][0][0] == 5
|
||||||
|
assert tm.call_args_list[3][0][0] == 10
|
||||||
|
assert api_mock.fetch_order.call_count == API_RETRY_COUNT + 1
|
||||||
|
|
||||||
ccxt_exceptionhandlers(mocker, default_conf, api_mock, exchange_name,
|
ccxt_exceptionhandlers(mocker, default_conf, api_mock, exchange_name,
|
||||||
'fetch_order', 'fetch_order',
|
'fetch_order', 'fetch_order',
|
||||||
order_id='_', pair='TKN/BTC')
|
order_id='_', pair='TKN/BTC')
|
||||||
|
@ -2078,7 +2078,7 @@ def test_check_handle_timedout_buy_exception(default_conf, ticker, limit_buy_ord
|
|||||||
'freqtrade.exchange.Exchange',
|
'freqtrade.exchange.Exchange',
|
||||||
validate_pairs=MagicMock(),
|
validate_pairs=MagicMock(),
|
||||||
fetch_ticker=ticker,
|
fetch_ticker=ticker,
|
||||||
fetch_order=MagicMock(side_effect=DependencyException),
|
fetch_order=MagicMock(side_effect=ExchangeError),
|
||||||
cancel_order=cancel_order_mock,
|
cancel_order=cancel_order_mock,
|
||||||
get_fee=fee
|
get_fee=fee
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user