diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 4cd8b51a4..137a47eaa 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -729,7 +729,7 @@ class FreqtradeBot(LoggingMixin): trades_closed += 1 except DependencyException as exception: - logger.warning('Unable to sell trade %s: %s', trade.pair, exception) + logger.warning(f'Unable to sell trade {trade.pair}: {exception}') # Updating wallets if any trade occurred if trades_closed: @@ -973,8 +973,12 @@ class FreqtradeBot(LoggingMixin): if max_timeouts > 0 and canceled_count >= max_timeouts: logger.warning(f'Emergencyselling trade {trade}, as the sell order ' f'timed out {max_timeouts} times.') - self.execute_trade_exit(trade, order.get('price'), sell_reason=SellCheckTuple( - sell_type=SellType.EMERGENCY_SELL)) + try: + self.execute_trade_exit( + trade, order.get('price'), + sell_reason=SellCheckTuple(sell_type=SellType.EMERGENCY_SELL)) + except DependencyException as exception: + logger.warning(f'Unable to emergency sell trade {trade.pair}: {exception}') def cancel_all_open_orders(self) -> None: """ diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index dd1fcd6e2..2d2664055 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -2171,10 +2171,20 @@ def test_check_handle_timedout_sell_usercustom(default_conf_usdt, ticker_usdt, l assert open_trade.is_open is True assert freqtrade.strategy.check_sell_timeout.call_count == 1 - # 2nd canceled trade ... + # 2nd canceled trade - Fail execute sell caplog.clear() open_trade.open_order_id = 'order_id_2' mocker.patch('freqtrade.persistence.Trade.get_exit_order_count', return_value=1) + mocker.patch('freqtrade.freqtradebot.FreqtradeBot.execute_trade_exit', + side_effect=DependencyException) + freqtrade.check_handle_timedout() + assert log_has_re('Unable to emergency sell .*', caplog) + + et_mock = mocker.patch('freqtrade.freqtradebot.FreqtradeBot.execute_trade_exit') + caplog.clear() + + # 2nd canceled trade ... + open_trade.open_order_id = 'order_id_2' freqtrade.check_handle_timedout() assert log_has_re('Emergencyselling trade.*', caplog) assert et_mock.call_count == 1 diff --git a/tests/test_misc.py b/tests/test_misc.py index de3f368e9..21a00f3be 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -184,16 +184,18 @@ def test_render_template_fallback(mocker): assert 'if self.dp' in val -def test_parse_db_uri_for_logging() -> None: - postgresql_conn_uri = "postgresql+psycopg2://scott123:scott123@host/dbname" - mariadb_conn_uri = "mariadb+mariadbconnector://app_user:Password123!@127.0.0.1:3306/company" - mysql_conn_uri = "mysql+pymysql://user:pass@some_mariadb/dbname?charset=utf8mb4" - sqlite_conn_uri = "sqlite:////freqtrade/user_data/tradesv3.sqlite" - censored_pwd = "*****" +@pytest.mark.parametrize('conn_url,expected', [ + ("postgresql+psycopg2://scott123:scott123@host:1245/dbname", + "postgresql+psycopg2://scott123:*****@host:1245/dbname"), + ("postgresql+psycopg2://scott123:scott123@host.name.com/dbname", + "postgresql+psycopg2://scott123:*****@host.name.com/dbname"), + ("mariadb+mariadbconnector://app_user:Password123!@127.0.0.1:3306/company", + "mariadb+mariadbconnector://app_user:*****@127.0.0.1:3306/company"), + ("mysql+pymysql://user:pass@some_mariadb/dbname?charset=utf8mb4", + "mysql+pymysql://user:*****@some_mariadb/dbname?charset=utf8mb4"), + ("sqlite:////freqtrade/user_data/tradesv3.sqlite", + "sqlite:////freqtrade/user_data/tradesv3.sqlite"), +]) +def test_parse_db_uri_for_logging(conn_url, expected) -> None: - def get_pwd(x): return x.split(':')[2].split('@')[0] - - assert get_pwd(parse_db_uri_for_logging(postgresql_conn_uri)) == censored_pwd - assert get_pwd(parse_db_uri_for_logging(mariadb_conn_uri)) == censored_pwd - assert get_pwd(parse_db_uri_for_logging(mysql_conn_uri)) == censored_pwd - assert sqlite_conn_uri == parse_db_uri_for_logging(sqlite_conn_uri) + assert parse_db_uri_for_logging(conn_url) == expected