Merge pull request #2055 from freqtrade/get_order_exception
Get order exception
This commit is contained in:
		| @@ -174,10 +174,10 @@ class Exchange(object): | |||||||
|         try: |         try: | ||||||
|  |  | ||||||
|             api = getattr(ccxt_module, name.lower())(ex_config) |             api = getattr(ccxt_module, name.lower())(ex_config) | ||||||
|         except (KeyError, AttributeError): |         except (KeyError, AttributeError) as e: | ||||||
|             raise OperationalException(f'Exchange {name} is not supported') |             raise OperationalException(f'Exchange {name} is not supported') from e | ||||||
|         except ccxt.BaseError as e: |         except ccxt.BaseError as e: | ||||||
|             raise OperationalException(f"Initialization of ccxt failed. Reason: {e}") |             raise OperationalException(f"Initialization of ccxt failed. Reason: {e}") from e | ||||||
|  |  | ||||||
|         self.set_sandbox(api, exchange_config, name) |         self.set_sandbox(api, exchange_config, name) | ||||||
|  |  | ||||||
| @@ -398,17 +398,17 @@ class Exchange(object): | |||||||
|             raise DependencyException( |             raise DependencyException( | ||||||
|                 f'Insufficient funds to create {ordertype} {side} order on market {pair}.' |                 f'Insufficient funds to create {ordertype} {side} order on market {pair}.' | ||||||
|                 f'Tried to {side} amount {amount} at rate {rate} (total {rate * amount}).' |                 f'Tried to {side} amount {amount} at rate {rate} (total {rate * amount}).' | ||||||
|                 f'Message: {e}') |                 f'Message: {e}') from e | ||||||
|         except ccxt.InvalidOrder as e: |         except ccxt.InvalidOrder as e: | ||||||
|             raise DependencyException( |             raise DependencyException( | ||||||
|                 f'Could not create {ordertype} {side} order on market {pair}.' |                 f'Could not create {ordertype} {side} order on market {pair}.' | ||||||
|                 f'Tried to {side} amount {amount} at rate {rate} (total {rate * amount}).' |                 f'Tried to {side} amount {amount} at rate {rate} (total {rate * amount}).' | ||||||
|                 f'Message: {e}') |                 f'Message: {e}') from e | ||||||
|         except (ccxt.NetworkError, ccxt.ExchangeError) as e: |         except (ccxt.NetworkError, ccxt.ExchangeError) as e: | ||||||
|             raise TemporaryError( |             raise TemporaryError( | ||||||
|                 f'Could not place {side} order due to {e.__class__.__name__}. Message: {e}') |                 f'Could not place {side} order due to {e.__class__.__name__}. Message: {e}') from e | ||||||
|         except ccxt.BaseError as e: |         except ccxt.BaseError as e: | ||||||
|             raise OperationalException(e) |             raise OperationalException(e) from e | ||||||
|  |  | ||||||
|     def buy(self, pair: str, ordertype: str, amount: float, |     def buy(self, pair: str, ordertype: str, amount: float, | ||||||
|             rate: float, time_in_force) -> Dict: |             rate: float, time_in_force) -> Dict: | ||||||
| @@ -493,9 +493,9 @@ class Exchange(object): | |||||||
|             return balances |             return balances | ||||||
|         except (ccxt.NetworkError, ccxt.ExchangeError) as e: |         except (ccxt.NetworkError, ccxt.ExchangeError) as e: | ||||||
|             raise TemporaryError( |             raise TemporaryError( | ||||||
|                 f'Could not get balance due to {e.__class__.__name__}. Message: {e}') |                 f'Could not get balance due to {e.__class__.__name__}. Message: {e}') from e | ||||||
|         except ccxt.BaseError as e: |         except ccxt.BaseError as e: | ||||||
|             raise OperationalException(e) |             raise OperationalException(e) from e | ||||||
|  |  | ||||||
|     @retrier |     @retrier | ||||||
|     def get_tickers(self) -> Dict: |     def get_tickers(self) -> Dict: | ||||||
| @@ -504,12 +504,12 @@ class Exchange(object): | |||||||
|         except ccxt.NotSupported as e: |         except ccxt.NotSupported as e: | ||||||
|             raise OperationalException( |             raise OperationalException( | ||||||
|                 f'Exchange {self._api.name} does not support fetching tickers in batch.' |                 f'Exchange {self._api.name} does not support fetching tickers in batch.' | ||||||
|                 f'Message: {e}') |                 f'Message: {e}') from e | ||||||
|         except (ccxt.NetworkError, ccxt.ExchangeError) as e: |         except (ccxt.NetworkError, ccxt.ExchangeError) as e: | ||||||
|             raise TemporaryError( |             raise TemporaryError( | ||||||
|                 f'Could not load tickers due to {e.__class__.__name__}. Message: {e}') |                 f'Could not load tickers due to {e.__class__.__name__}. Message: {e}') from e | ||||||
|         except ccxt.BaseError as e: |         except ccxt.BaseError as e: | ||||||
|             raise OperationalException(e) |             raise OperationalException(e) from e | ||||||
|  |  | ||||||
|     @retrier |     @retrier | ||||||
|     def get_ticker(self, pair: str, refresh: Optional[bool] = True) -> dict: |     def get_ticker(self, pair: str, refresh: Optional[bool] = True) -> dict: | ||||||
| @@ -528,9 +528,9 @@ class Exchange(object): | |||||||
|                 return data |                 return data | ||||||
|             except (ccxt.NetworkError, ccxt.ExchangeError) as e: |             except (ccxt.NetworkError, ccxt.ExchangeError) as e: | ||||||
|                 raise TemporaryError( |                 raise TemporaryError( | ||||||
|                     f'Could not load ticker due to {e.__class__.__name__}. Message: {e}') |                     f'Could not load ticker due to {e.__class__.__name__}. Message: {e}') from e | ||||||
|             except ccxt.BaseError as e: |             except ccxt.BaseError as e: | ||||||
|                 raise OperationalException(e) |                 raise OperationalException(e) from e | ||||||
|         else: |         else: | ||||||
|             logger.info("returning cached ticker-data for %s", pair) |             logger.info("returning cached ticker-data for %s", pair) | ||||||
|             return self._cached_ticker[pair] |             return self._cached_ticker[pair] | ||||||
| @@ -651,12 +651,12 @@ class Exchange(object): | |||||||
|         except ccxt.NotSupported as e: |         except ccxt.NotSupported as e: | ||||||
|             raise OperationalException( |             raise OperationalException( | ||||||
|                 f'Exchange {self._api.name} does not support fetching historical candlestick data.' |                 f'Exchange {self._api.name} does not support fetching historical candlestick data.' | ||||||
|                 f'Message: {e}') |                 f'Message: {e}') from e | ||||||
|         except (ccxt.NetworkError, ccxt.ExchangeError) as e: |         except (ccxt.NetworkError, ccxt.ExchangeError) as e: | ||||||
|             raise TemporaryError( |             raise TemporaryError(f'Could not load ticker history due to {e.__class__.__name__}. ' | ||||||
|                 f'Could not load ticker history due to {e.__class__.__name__}. Message: {e}') |                                  f'Message: {e}') from e | ||||||
|         except ccxt.BaseError as e: |         except ccxt.BaseError as e: | ||||||
|             raise OperationalException(f'Could not fetch ticker data. Msg: {e}') |             raise OperationalException(f'Could not fetch ticker data. Msg: {e}') from e | ||||||
|  |  | ||||||
|     @retrier |     @retrier | ||||||
|     def cancel_order(self, order_id: str, pair: str) -> None: |     def cancel_order(self, order_id: str, pair: str) -> None: | ||||||
| @@ -667,12 +667,12 @@ class Exchange(object): | |||||||
|             return self._api.cancel_order(order_id, pair) |             return self._api.cancel_order(order_id, pair) | ||||||
|         except ccxt.InvalidOrder as e: |         except ccxt.InvalidOrder as e: | ||||||
|             raise InvalidOrderException( |             raise InvalidOrderException( | ||||||
|                 f'Could not cancel order. Message: {e}') |                 f'Could not cancel order. Message: {e}') from e | ||||||
|         except (ccxt.NetworkError, ccxt.ExchangeError) as e: |         except (ccxt.NetworkError, ccxt.ExchangeError) as e: | ||||||
|             raise TemporaryError( |             raise TemporaryError( | ||||||
|                 f'Could not cancel order due to {e.__class__.__name__}. Message: {e}') |                 f'Could not cancel order due to {e.__class__.__name__}. Message: {e}') from e | ||||||
|         except ccxt.BaseError as e: |         except ccxt.BaseError as e: | ||||||
|             raise OperationalException(e) |             raise OperationalException(e) from e | ||||||
|  |  | ||||||
|     @retrier |     @retrier | ||||||
|     def get_order(self, order_id: str, pair: str) -> Dict: |     def get_order(self, order_id: str, pair: str) -> Dict: | ||||||
| @@ -683,12 +683,12 @@ class Exchange(object): | |||||||
|             return self._api.fetch_order(order_id, pair) |             return self._api.fetch_order(order_id, pair) | ||||||
|         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}') |                 f'Tried to get an invalid order (id: {order_id}). Message: {e}') from e | ||||||
|         except (ccxt.NetworkError, ccxt.ExchangeError) as e: |         except (ccxt.NetworkError, ccxt.ExchangeError) as e: | ||||||
|             raise TemporaryError( |             raise TemporaryError( | ||||||
|                 f'Could not get order due to {e.__class__.__name__}. Message: {e}') |                 f'Could not get order due to {e.__class__.__name__}. Message: {e}') from e | ||||||
|         except ccxt.BaseError as e: |         except ccxt.BaseError as e: | ||||||
|             raise OperationalException(e) |             raise OperationalException(e) from e | ||||||
|  |  | ||||||
|     @retrier |     @retrier | ||||||
|     def get_order_book(self, pair: str, limit: int = 100) -> dict: |     def get_order_book(self, pair: str, limit: int = 100) -> dict: | ||||||
| @@ -704,12 +704,12 @@ class Exchange(object): | |||||||
|         except ccxt.NotSupported as e: |         except ccxt.NotSupported as e: | ||||||
|             raise OperationalException( |             raise OperationalException( | ||||||
|                 f'Exchange {self._api.name} does not support fetching order book.' |                 f'Exchange {self._api.name} does not support fetching order book.' | ||||||
|                 f'Message: {e}') |                 f'Message: {e}') from e | ||||||
|         except (ccxt.NetworkError, ccxt.ExchangeError) as e: |         except (ccxt.NetworkError, ccxt.ExchangeError) as e: | ||||||
|             raise TemporaryError( |             raise TemporaryError( | ||||||
|                 f'Could not get order book due to {e.__class__.__name__}. Message: {e}') |                 f'Could not get order book due to {e.__class__.__name__}. Message: {e}') from e | ||||||
|         except ccxt.BaseError as e: |         except ccxt.BaseError as e: | ||||||
|             raise OperationalException(e) |             raise OperationalException(e) from e | ||||||
|  |  | ||||||
|     @retrier |     @retrier | ||||||
|     def get_trades_for_order(self, order_id: str, pair: str, since: datetime) -> List: |     def get_trades_for_order(self, order_id: str, pair: str, since: datetime) -> List: | ||||||
| @@ -726,9 +726,9 @@ class Exchange(object): | |||||||
|  |  | ||||||
|         except ccxt.NetworkError as e: |         except ccxt.NetworkError as e: | ||||||
|             raise TemporaryError( |             raise TemporaryError( | ||||||
|                 f'Could not get trades due to networking error. Message: {e}') |                 f'Could not get trades due to networking error. Message: {e}') from e | ||||||
|         except ccxt.BaseError as e: |         except ccxt.BaseError as e: | ||||||
|             raise OperationalException(e) |             raise OperationalException(e) from e | ||||||
|  |  | ||||||
|     @retrier |     @retrier | ||||||
|     def get_fee(self, symbol='ETH/BTC', type='', side='', amount=1, |     def get_fee(self, symbol='ETH/BTC', type='', side='', amount=1, | ||||||
| @@ -742,9 +742,9 @@ class Exchange(object): | |||||||
|                                            price=price, takerOrMaker=taker_or_maker)['rate'] |                                            price=price, takerOrMaker=taker_or_maker)['rate'] | ||||||
|         except (ccxt.NetworkError, ccxt.ExchangeError) as e: |         except (ccxt.NetworkError, ccxt.ExchangeError) as e: | ||||||
|             raise TemporaryError( |             raise TemporaryError( | ||||||
|                 f'Could not get fee info due to {e.__class__.__name__}. Message: {e}') |                 f'Could not get fee info due to {e.__class__.__name__}. Message: {e}') from e | ||||||
|         except ccxt.BaseError as e: |         except ccxt.BaseError as e: | ||||||
|             raise OperationalException(e) |             raise OperationalException(e) from e | ||||||
|  |  | ||||||
|  |  | ||||||
| def is_exchange_bad(exchange: str) -> bool: | def is_exchange_bad(exchange: str) -> bool: | ||||||
|   | |||||||
| @@ -524,7 +524,11 @@ class FreqtradeBot(object): | |||||||
|         if trade.open_order_id: |         if trade.open_order_id: | ||||||
|             # Update trade with order values |             # Update trade with order values | ||||||
|             logger.info('Found open order for %s', trade) |             logger.info('Found open order for %s', trade) | ||||||
|  |             try: | ||||||
|                 order = action_order or self.exchange.get_order(trade.open_order_id, trade.pair) |                 order = action_order or self.exchange.get_order(trade.open_order_id, trade.pair) | ||||||
|  |             except InvalidOrderException as exception: | ||||||
|  |                 logger.warning('Unable to fetch order %s: %s', trade.open_order_id, exception) | ||||||
|  |                 return | ||||||
|             # Try update amount (binance-fix) |             # Try update amount (binance-fix) | ||||||
|             try: |             try: | ||||||
|                 new_amount = self.get_real_amount(trade, order) |                 new_amount = self.get_real_amount(trade, order) | ||||||
| @@ -749,7 +753,7 @@ class FreqtradeBot(object): | |||||||
|                 if not trade.open_order_id: |                 if not trade.open_order_id: | ||||||
|                     continue |                     continue | ||||||
|                 order = self.exchange.get_order(trade.open_order_id, trade.pair) |                 order = self.exchange.get_order(trade.open_order_id, trade.pair) | ||||||
|             except (RequestException, DependencyException): |             except (RequestException, DependencyException, InvalidOrderException): | ||||||
|                 logger.info( |                 logger.info( | ||||||
|                     'Cannot query order for %s due to %s', |                     'Cannot query order for %s due to %s', | ||||||
|                     trade, |                     trade, | ||||||
|   | |||||||
| @@ -1460,6 +1460,22 @@ def test_update_trade_state_exception(mocker, default_conf, | |||||||
|     assert log_has('Could not update trade amount: ', caplog.record_tuples) |     assert log_has('Could not update trade amount: ', caplog.record_tuples) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def test_update_trade_state_orderexception(mocker, default_conf, caplog) -> None: | ||||||
|  |     freqtrade = get_patched_freqtradebot(mocker, default_conf) | ||||||
|  |     mocker.patch('freqtrade.exchange.Exchange.get_order', | ||||||
|  |                  MagicMock(side_effect=InvalidOrderException)) | ||||||
|  |  | ||||||
|  |     trade = MagicMock() | ||||||
|  |     trade.open_order_id = '123' | ||||||
|  |     trade.open_fee = 0.001 | ||||||
|  |  | ||||||
|  |     # Test raise of OperationalException exception | ||||||
|  |     grm_mock = mocker.patch("freqtrade.freqtradebot.FreqtradeBot.get_real_amount", MagicMock()) | ||||||
|  |     freqtrade.update_trade_state(trade) | ||||||
|  |     assert grm_mock.call_count == 0 | ||||||
|  |     assert log_has(f'Unable to fetch order {trade.open_order_id}: ', caplog.record_tuples) | ||||||
|  |  | ||||||
|  |  | ||||||
| def test_update_trade_state_sell(default_conf, trades_for_order, limit_sell_order, mocker): | def test_update_trade_state_sell(default_conf, trades_for_order, limit_sell_order, mocker): | ||||||
|     mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order', return_value=trades_for_order) |     mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order', return_value=trades_for_order) | ||||||
|     # get_order should not be called!! |     # get_order should not be called!! | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user