diff --git a/golem/ethereum/exceptions.py b/golem/ethereum/exceptions.py index 5f01c9709b..840551da7b 100644 --- a/golem/ethereum/exceptions.py +++ b/golem/ethereum/exceptions.py @@ -42,7 +42,7 @@ def single_currency( ]) def __str__(self) -> str: - return "Not enough funds available.\n" + self._missing_funds_to_str() + return "Not enough funds available." + self._missing_funds_to_str() def to_dict(self) -> dict: err_dict = super().to_dict() @@ -54,15 +54,15 @@ def to_dict(self) -> dict: def _missing_funds_to_str(self) -> str: res = "" for required, available, currency in self.missing_funds: - res += f"Required {currency}: {required / denoms.ether:f}, " \ - f"available: {available / denoms.ether:f}\n" + res += f" Required {currency}: {required / denoms.ether:f}, " \ + f"available: {available / denoms.ether:f}." return res class NotEnoughDepositFunds(NotEnoughFunds): def __str__(self) -> str: - return "Not enough funds for Concent deposit." \ + return "Not enough funds for Concent deposit. " \ "Top up your account or create the task with Concent disabled." \ + self._missing_funds_to_str() diff --git a/golem/task/rpc.py b/golem/task/rpc.py index 87f7893f77..ad94897838 100644 --- a/golem/task/rpc.py +++ b/golem/task/rpc.py @@ -421,10 +421,19 @@ def enqueue_new_task(client, task, force=False) \ return task -def _create_task_error(e, _self, task_dict, *args, **_kwargs) \ - -> typing.Tuple[None, typing.Union[str, typing.Dict]]: +def _create_task_error( + e: Exception, + self: 'ClientProvider', + task_dict: dict, + *_args, + **kwargs +) -> typing.Tuple[None, typing.Union[str, typing.Dict]]: logger.error("Cannot create task %r: %s", task_dict, e) + task_id = kwargs.get('task_id') + if task_id: + self.task_manager.task_creation_failed(task_id, str(e)) + if hasattr(e, 'to_dict'): return None, rpc_utils.int_to_string(e.to_dict()) @@ -521,19 +530,23 @@ def _create_legacy_task( self, task_dict: dict, force: bool = False, - ) -> typing.Tuple[TaskId, typing.Optional[str]]: + ) -> typing.Tuple[typing.Optional[TaskId], + typing.Optional[typing.Union[str, typing.Dict]]]: logger.info('Creating task. task_dict=%r', task_dict) logger.debug('force=%r', force) task = _create_task(self.client, task_dict) task_id = task.header.task_id - self._validate_enough_funds_to_pay_for_task( - task.subtask_price, - task.get_total_tasks(), - task.header.concent_enabled, - force - ) + try: + self._validate_enough_funds_to_pay_for_task( + task.subtask_price, + task.get_total_tasks(), + task.header.concent_enabled, + force + ) + except eth_exceptions.NotEnoughFunds as e: + return _create_task_error(e, self, task_dict, task_id=task_id) # Fire and forget the next steps after create_task deferred = _prepare_task(client=self.client, task=task, force=force) diff --git a/golem/task/taskmanager.py b/golem/task/taskmanager.py index 484673eddc..2f2a0c8e7d 100644 --- a/golem/task/taskmanager.py +++ b/golem/task/taskmanager.py @@ -994,7 +994,6 @@ def put_task_in_failed_state( task_status=TaskStatus.errorCreating, ) -> None: assert not task_status.is_active() - assert not task_status.is_completed() task_state = self.tasks_states[task_id] if task_state.status.is_completed(): logger.debug( diff --git a/golem/task/taskstate.py b/golem/task/taskstate.py index 9ac56e34bf..a1b20f3f4d 100644 --- a/golem/task/taskstate.py +++ b/golem/task/taskstate.py @@ -196,7 +196,8 @@ def is_active(self) -> bool: TaskStatus.finished, TaskStatus.aborted, TaskStatus.timeout, - TaskStatus.restarted + TaskStatus.restarted, + TaskStatus.errorCreating, ] diff --git a/tests/golem/ethereum/test_exceptions.py b/tests/golem/ethereum/test_exceptions.py index 97d9a4afa9..0431dc5d63 100644 --- a/tests/golem/ethereum/test_exceptions.py +++ b/tests/golem/ethereum/test_exceptions.py @@ -14,8 +14,8 @@ def test_error_message_single_currency(self): currency='GNT' ) except NotEnoughFunds as err: - expected = f'Not enough funds available.\n' \ - f'Required GNT: 5.000000, available: 1.000000\n' + expected = f'Not enough funds available. ' \ + f'Required GNT: 5.000000, available: 1.000000.' self.assertIn(str(err), expected) def test_error_message_multiple_currencies(self): @@ -35,9 +35,9 @@ def test_error_message_multiple_currencies(self): try: raise NotEnoughFunds(missing_funds) except NotEnoughFunds as err: - expected = f'Not enough funds available.\n' \ - f'Required ETH: 5.000000, available: 1.000000\n' \ - f'Required GNT: 1.000000, available: 0.000000\n' + expected = f'Not enough funds available. ' \ + f'Required ETH: 5.000000, available: 1.000000. ' \ + f'Required GNT: 1.000000, available: 0.000000.' self.assertIn(str(err), expected) def test_error_to_dict(self): diff --git a/tests/golem/task/test_rpc.py b/tests/golem/task/test_rpc.py index 3f8ee5145d..0972aeb5d0 100644 --- a/tests/golem/task/test_rpc.py +++ b/tests/golem/task/test_rpc.py @@ -205,9 +205,9 @@ def test_create_task_fail_if_not_enough_gnt_available(self, mocked, *_): error = result[1] # noqa pylint:disable=unsubscriptable-object self.assertEqual(error['error_type'], 'NotEnoughFunds') - self.assertEqual(error['error_msg'], 'Not enough funds available.\n' + self.assertEqual(error['error_msg'], 'Not enough funds available. ' 'Required GNT: ' - '0.166667, available: 0.000000\n') + '0.166667, available: 0.000000.') @mock.patch('golem.task.rpc.ClientProvider.' '_validate_enough_funds_to_pay_for_task') @@ -277,11 +277,11 @@ def test_validate_lock_funds_possibility_raises_if_not_enough_funds(self): subtask_price=required_gnt, subtask_count=1 ) - expected = f'Not enough funds available.\n' \ + expected = f'Not enough funds available. ' \ f'Required GNT: {required_gnt / denoms.ether:f}, ' \ - f'available: {available_gnt / denoms.ether:f}\n' \ + f'available: {available_gnt / denoms.ether:f}. ' \ f'Required ETH: {required_eth / denoms.ether:f}, ' \ - f'available: {available_eth / denoms.ether:f}\n' + f'available: {available_eth / denoms.ether:f}. ' self.assertIn(str(e.exception), expected)