From 30e3b52b1e7f02b8a159acefa99627b6ad1104c7 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 19 Jan 2019 20:02:37 +0100 Subject: [PATCH 1/3] catch errors found in #1491 --- freqtrade/exchange/__init__.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/freqtrade/exchange/__init__.py b/freqtrade/exchange/__init__.py index 90a33a226..b8d32306e 100644 --- a/freqtrade/exchange/__init__.py +++ b/freqtrade/exchange/__init__.py @@ -556,12 +556,17 @@ class Exchange(object): tickers = await asyncio.gather(*input_coroutines, return_exceptions=True) # handle caching - for pair, ticks in tickers: + for res in tickers: + if isinstance(res, Exception): + logger.warning("Async code raised an exception: %s", res.__class__.__name__) + continue + pair = res[0] + ticks = res[1] # keeping last candle time as last refreshed time of the pair if ticks: self._pairs_last_refresh_time[pair] = ticks[-1][0] // 1000 - # keeping parsed dataframe in cache - self._klines[pair] = parse_ticker_dataframe(ticks, tick_interval, fill_missing=True) + # keeping parsed dataframe in cache + self._klines[pair] = parse_ticker_dataframe(ticks, tick_interval, fill_missing=True) return tickers @retrier_async @@ -578,9 +583,12 @@ class Exchange(object): # Ex: Bittrex returns a list of tickers ASC (oldest first, newest last) # when GDAX returns a list of tickers DESC (newest first, oldest last) # Only sort if necessary to save computing time - if data and data[0][0] > data[-1][0]: - data = sorted(data, key=lambda x: x[0]) - + try: + if data and data[0][0] > data[-1][0]: + data = sorted(data, key=lambda x: x[0]) + except IndexError: + logger.exception("Error loading %s. Result was %s.", pair, data) + return pair, None logger.debug("done fetching %s ...", pair) return pair, data From 4e760e1a5e52e213be77931ed4f9586f5de7cdb1 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 19 Jan 2019 20:03:04 +0100 Subject: [PATCH 2/3] Test for errors found in 1491 fixes #1491 --- freqtrade/tests/exchange/test_exchange.py | 24 +++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/freqtrade/tests/exchange/test_exchange.py b/freqtrade/tests/exchange/test_exchange.py index 29154bc39..26808e78a 100644 --- a/freqtrade/tests/exchange/test_exchange.py +++ b/freqtrade/tests/exchange/test_exchange.py @@ -923,6 +923,30 @@ async def test_async_get_candles_history(default_conf, mocker): assert exchange._async_get_candle_history.call_count == 2 +@pytest.mark.asyncio +async def test_async_get_candles_history_inv_result(default_conf, mocker, caplog): + + async def mock_get_candle_hist(pair, *args, **kwargs): + if pair == 'ETH/BTC': + return [[]] + else: + raise TypeError() + + exchange = get_patched_exchange(mocker, default_conf) + + # Monkey-patch async function with empty result + exchange._api_async.fetch_ohlcv = MagicMock(side_effect=mock_get_candle_hist) + + pairs = ['ETH/BTC', 'XRP/BTC'] + res = await exchange.async_get_candles_history(pairs, "5m") + assert type(res) is list + assert len(res) == 2 + assert type(res[0]) is tuple + assert type(res[1]) is TypeError + assert log_has("Error loading ETH/BTC. Result was [[]].", caplog.record_tuples) + assert log_has("Async code raised an exception: TypeError", caplog.record_tuples) + + def test_get_order_book(default_conf, mocker, order_book_l2): default_conf['exchange']['name'] = 'binance' api_mock = MagicMock() From b48430f9221c33407dc6c35d890ba916a0876a8a Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 19 Jan 2019 20:21:33 +0100 Subject: [PATCH 3/3] Return list not None --- freqtrade/exchange/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/exchange/__init__.py b/freqtrade/exchange/__init__.py index b8d32306e..e0e4d7723 100644 --- a/freqtrade/exchange/__init__.py +++ b/freqtrade/exchange/__init__.py @@ -588,7 +588,7 @@ class Exchange(object): data = sorted(data, key=lambda x: x[0]) except IndexError: logger.exception("Error loading %s. Result was %s.", pair, data) - return pair, None + return pair, [] logger.debug("done fetching %s ...", pair) return pair, data