diff --git a/docs/recovery_and_error_logging.md b/docs/recovery_and_error_logging.md index 36be248..679e6ae 100644 --- a/docs/recovery_and_error_logging.md +++ b/docs/recovery_and_error_logging.md @@ -65,8 +65,9 @@ has its own **consecutive failure counter**: - The disable is **session-only / in-memory** — it does not edit `params.ini`. Restarting the bot re-enables the run. This is intentional so a transient problem (e.g. a game hiccup) doesn't permanently change your config. -- If **all** runs end up disabled, the bot stops/restarts for investigation rather - than looping over empty games. +- If **all** runs end up disabled there are no routes left, so the bot saves a + session report and stops cleanly (kills the game and exits) rather than looping + over empty games or pointlessly restarting D2R. ### Config diff --git a/src/bot.py b/src/bot.py index 6e7c915..41b4c63 100644 --- a/src/bot.py +++ b/src/bot.py @@ -754,13 +754,22 @@ class Bot: if self._messenger.enabled: self._messenger.send_message(msg) - # If everything has now been disabled there is nothing left to do. + # If everything has now been disabled there are no routes left to run, + # so stop the bot cleanly (no point restarting D2R into empty games). if all(not v for v in self._do_runs_reset.values()): - crit = "All runs have been disabled due to repeated failures. Stopping bot for investigation." + crit = "All runs have been disabled due to repeated failures — no routes left. Stopping bot." Logger.error(crit) + if not self._game_stats.get_failure_reason(): + self._game_stats.set_failure_reason(crit) if self._messenger.enabled: self._messenger.send_message(crit) - self.restart_or_exit(crit) + # Persist a session report for review, then shut down. + try: + self._game_stats._save_session_report() + except Exception as e: + Logger.warning(f"Failed to save session report on shutdown: {e}") + self.stop() + safe_exit() def _ending_run_helper(self, res: bool | tuple[Location, bool]): self._game_stats._run_counter += 1