diff --git a/run.py b/run.py index b102868..15a4a8e 100644 --- a/run.py +++ b/run.py @@ -1,6 +1,80 @@ -"""PyInstaller entry shim.""" +"""PyInstaller entry shim. + +Wrapped in a top-level try/except so any startup failure is written to +%LOCALAPPDATA%\\sephiria_inv\\startup.log and surfaced to the user via a +Tk messagebox when possible. Without this wrapper, --noconsole builds +exit silently on import-time errors and the user sees "nothing happens". +""" + +from __future__ import annotations + +import os +import sys +import traceback +from datetime import datetime + + +def _log_path() -> str: + base = os.environ.get("LOCALAPPDATA") or os.path.expanduser("~") + folder = os.path.join(base, "sephiria_inv") + try: + os.makedirs(folder, exist_ok=True) + except OSError: + folder = os.path.dirname(os.path.abspath(sys.argv[0])) or "." + return os.path.join(folder, "startup.log") + + +def _write_log(msg: str) -> str: + path = _log_path() + try: + with open(path, "a", encoding="utf-8") as fh: + fh.write(f"\n=== {datetime.now().isoformat()} ===\n{msg}\n") + except OSError: + pass + return path + + +def _show_error(title: str, body: str) -> None: + try: + import tkinter as tk + from tkinter import scrolledtext + root = tk.Tk() + root.title(title) + root.geometry("760x420") + txt = scrolledtext.ScrolledText(root, wrap="word") + txt.pack(fill="both", expand=True) + txt.insert("1.0", body) + tk.Button(root, text="Close", command=root.destroy).pack(pady=4) + root.mainloop() + except Exception: + # Tk itself is broken; nothing we can show. + pass + + +def _main() -> int: + try: + from sephiria_inv.__main__ import main + except BaseException: + tb = traceback.format_exc() + log = _write_log("IMPORT FAIL\n" + tb) + _show_error( + "sephiria_inv: import failed", + f"Failed to import sephiria_inv.__main__\n\nLog: {log}\n\n{tb}", + ) + return 11 + try: + return int(main() or 0) + except SystemExit: + raise + except BaseException: + tb = traceback.format_exc() + log = _write_log("RUNTIME FAIL\n" + tb) + _show_error( + "sephiria_inv: runtime error", + f"Crashed during main()\n\nLog: {log}\n\n{tb}", + ) + return 12 -from sephiria_inv.__main__ import main if __name__ == "__main__": - raise SystemExit(main()) + raise SystemExit(_main())