Skip to content

Commit 9e30d7d

Browse files
authored
Catch and show game list errors at startup (#177)
* Catch and log errors for failed EA games list parsing * Extend error logging for Epic Games * Add error message box for errors loading game list * Fix lint error in game_sims4.py
1 parent 59487e7 commit 9e30d7d

4 files changed

Lines changed: 65 additions & 16 deletions

File tree

basic_game.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import mobase
99
from PyQt6.QtCore import QDir, QFileInfo, QStandardPaths
1010
from PyQt6.QtGui import QIcon
11+
from PyQt6.QtWidgets import QMessageBox
1112

1213
from .basic_features.basic_save_game_info import (
1314
BasicGameSaveGame,
@@ -380,11 +381,22 @@ def setup():
380381
from .origin_utils import find_games as find_origin_games
381382
from .steam_utils import find_games as find_steam_games
382383

384+
errors: list[tuple[str, Exception]] = []
383385
BasicGame.steam_games = find_steam_games()
384386
BasicGame.gog_games = find_gog_games()
385387
BasicGame.origin_games = find_origin_games()
386-
BasicGame.epic_games = find_epic_games()
387-
BasicGame.eadesktop_games = find_eadesktop_games()
388+
BasicGame.epic_games = find_epic_games(errors)
389+
BasicGame.eadesktop_games = find_eadesktop_games(errors)
390+
391+
if errors:
392+
QMessageBox.critical(
393+
None,
394+
"Errors loading game list",
395+
(
396+
"The following errors occurred while loading the list of available games:\n"
397+
f"\n- {'\n\n- '.join('\n '.join(str(e) for e in messageError) for messageError in errors)}"
398+
),
399+
)
388400

389401
# File containing the plugin:
390402
_fromName: str

eadesktop_utils.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22

33
import configparser
44
import os
5+
import sys
56
import xml.etree.ElementTree as et
67
from configparser import NoOptionError
78
from pathlib import Path
89
from typing import Dict
910

1011

11-
def find_games() -> Dict[str, Path]:
12+
def find_games(errors: list[tuple[str, Exception]] | None = None) -> Dict[str, Path]:
1213
"""
1314
Find the list of EA Desktop games installed.
1415
@@ -37,7 +38,17 @@ def find_games() -> Dict[str, Path]:
3738
ini_content = "[mod_organizer]\n" + f.read()
3839

3940
config = configparser.ConfigParser()
40-
config.read_string(ini_content)
41+
try:
42+
config.read_string(ini_content)
43+
except configparser.ParsingError as e:
44+
error_message = (
45+
f'Failed to parse EA Desktop games list file "{user_ini}",\n'
46+
" Try to run the launcher to recreate it."
47+
)
48+
print(error_message, e, file=sys.stderr)
49+
if errors is not None:
50+
errors.append((error_message, e))
51+
return games
4152

4253
try:
4354
install_path = Path(config.get("mod_organizer", "user.downloadinplacedir"))

epic_utils.py

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,12 @@
99
from collections.abc import Iterable
1010
from pathlib import Path
1111

12+
ErrorList = list[tuple[str, Exception]]
1213

13-
def find_epic_games() -> Iterable[tuple[str, Path]]:
14+
15+
def find_epic_games(
16+
errors: ErrorList | None = None,
17+
) -> Iterable[tuple[str, Path]]:
1418
try:
1519
with winreg.OpenKey(
1620
winreg.HKEY_LOCAL_MACHINE,
@@ -30,15 +34,23 @@ def find_epic_games() -> Iterable[tuple[str, Path]]:
3034
manifest_file_data["AppName"],
3135
Path(manifest_file_data["InstallLocation"]),
3236
)
33-
except (json.JSONDecodeError, KeyError):
37+
except (json.JSONDecodeError, KeyError) as e:
38+
error_message = (
39+
f'Unable to parse Epic Games manifest file: "{manifest_file_path}"\n'
40+
" Try to run the launcher recreate it."
41+
)
3442
print(
35-
"Unable to parse Epic Games manifest file",
36-
manifest_file_path,
43+
error_message,
44+
e,
3745
file=sys.stderr,
3846
)
47+
if errors is not None:
48+
errors.append((error_message, e))
3949

4050

41-
def find_legendary_games(config_path: str | None = None) -> Iterable[tuple[str, Path]]:
51+
def find_legendary_games(
52+
config_path: str | None = None, errors: ErrorList | None = None
53+
) -> Iterable[tuple[str, Path]]:
4254
# Based on legendary source:
4355
# https://github.com/derrod/legendary/blob/master/legendary/lfs/lgndry.py
4456
if config_path := config_path or os.environ.get("XDG_CONFIG_HOME"):
@@ -53,21 +65,33 @@ def find_legendary_games(config_path: str | None = None) -> Iterable[tuple[str,
5365
installed_games = json.load(installed_file)
5466
for game in installed_games.values():
5567
yield game["app_name"], Path(game["install_path"])
56-
except (json.JSONDecodeError, AttributeError, KeyError):
68+
except (json.JSONDecodeError, AttributeError, KeyError) as e:
69+
error_message = (
70+
f'Unable to parse installed games from Legendary/Heroic launcher: "{installed_path}"\n'
71+
" Try to run the launcher to recrated the file."
72+
)
5773
print(
58-
"Unable to parse installed games from Legendary",
59-
installed_path,
74+
error_message,
75+
e,
6076
file=sys.stderr,
6177
)
78+
if errors is not None:
79+
errors.append((error_message, e))
6280

6381

64-
def find_heroic_games():
65-
return find_legendary_games(os.path.expandvars(r"%AppData%\heroic\legendaryConfig"))
82+
def find_heroic_games(errors: ErrorList | None = None):
83+
return find_legendary_games(
84+
os.path.expandvars(r"%AppData%\heroic\legendaryConfig"), errors
85+
)
6686

6787

68-
def find_games() -> dict[str, Path]:
88+
def find_games(errors: ErrorList | None = None) -> dict[str, Path]:
6989
return dict(
70-
itertools.chain(find_epic_games(), find_legendary_games(), find_heroic_games())
90+
itertools.chain(
91+
find_epic_games(errors=errors),
92+
find_legendary_games(errors=errors),
93+
find_heroic_games(errors=errors),
94+
)
7195
)
7296

7397

games/game_sims4.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ def fixOrValidateEntry(
111111
ValidationResult.FIXABLE,
112112
lambda: tree.move(entry, innerPath),
113113
)
114+
case _:
115+
pass
114116
return walkReturn
115117

116118
tree.walk(fixOrValidateEntry)

0 commit comments

Comments
 (0)