Skip to content

Commit eeb0063

Browse files
committed
Fix silenced IO errors during library discovery
The exception handler used here was meant to return an empty list of library folders if the VDF configuration file is empty. However, it also included the actual parsing process as well, causing any unrelated IO errors to be treated as the configuration file missing and all found library folders to be discarded. No warning message was also logged in this situation, even if it would make perfect sense to do so. Fix this issue by moving VDF file and by performing the path resolving for each Steam library path resolving in its own block. Fixes #436
1 parent 2e6ed4d commit eeb0063

File tree

1 file changed

+101
-72
lines changed

1 file changed

+101
-72
lines changed

src/protontricks/steam.py

Lines changed: 101 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -983,6 +983,84 @@ def get_steam_lib_paths(steam_path):
983983
Return a list of any Steam directories including any user-added
984984
Steam library folders
985985
"""
986+
def resolve_library_folder(path):
987+
"""
988+
Resolve the Steam library folder for the given path found in
989+
`libraryfolders.vdf` file. The final path is located in the
990+
case-insensitive `steamapps` directory.
991+
"""
992+
xdg_steam_path = Path.home() / ".local/share/Steam"
993+
flatpak_steam_path = \
994+
Path.home() / ".var/app/com.valvesoftware.Steam/data/Steam"
995+
996+
is_library_folder_xdg_steam = str(path) == str(xdg_steam_path)
997+
is_flatpak_steam = str(steam_path) == str(flatpak_steam_path)
998+
999+
# Adjust the path if the library folder is "~/.local/share/Steam"
1000+
# and we're looking for library folders in
1001+
# "~/.var/app/com.valvesoftware.Steam"
1002+
# This is because ~/.local/share/Steam inside a Steam Flatpak
1003+
# sandbox corresponds to a different location, and we need to
1004+
# adjust for that.
1005+
if is_library_folder_xdg_steam and is_flatpak_steam:
1006+
path = flatpak_steam_path
1007+
1008+
# Steam matches library folders case-insensitively.
1009+
candidates = [
1010+
candidate
1011+
for candidate in path.parent.iterdir()
1012+
if candidate.name.lower() == path.name.lower()
1013+
]
1014+
1015+
logger.debug(
1016+
"Following candidates found for the Steam library path %s: %s",
1017+
path, candidates
1018+
)
1019+
1020+
if not candidates:
1021+
logger.warning(
1022+
"Steam library folder %s in Steam configuration does not "
1023+
"exist",
1024+
path
1025+
)
1026+
return None
1027+
1028+
# In case of multiple matches, prioritize those that contain
1029+
# a 'steamapps' subdirectory
1030+
candidates.sort(
1031+
key=lambda path: any(
1032+
path.name.lower() == "steamapps"
1033+
for path in path.iterdir()
1034+
),
1035+
reverse=True
1036+
)
1037+
1038+
# In case multiple directories match, pick the first one,
1039+
# log a warning and hope for the best
1040+
if len(candidates) > 1:
1041+
logger.warning(
1042+
"Multiple Steam library folders with name %s were found. "
1043+
"Selecting %s.",
1044+
path, candidates[0]
1045+
)
1046+
1047+
if candidates[0].name != path.name:
1048+
logger.warning(
1049+
"Steam library folder %s in configuration differs from "
1050+
"found path %s. Was this directory renamed?",
1051+
path, candidates[0]
1052+
)
1053+
1054+
path = candidates[0]
1055+
1056+
logger.debug(
1057+
"Found Steam library folder %s. Is Flatpak path: %s, "
1058+
"Is XDG Steam path: %s.",
1059+
path, is_flatpak_steam, is_library_folder_xdg_steam
1060+
)
1061+
1062+
return path
1063+
9861064
def parse_library_folders(data):
9871065
"""
9881066
Parse the Steam library folders in the VDF file using the given data
@@ -1004,78 +1082,18 @@ def parse_library_folders(data):
10041082
# and nothing else
10051083
path = Path(value)
10061084

1007-
xdg_steam_path = Path.home() / ".local/share/Steam"
1008-
flatpak_steam_path = \
1009-
Path.home() / ".var/app/com.valvesoftware.Steam/data/Steam"
1010-
1011-
is_library_folder_xdg_steam = str(path) == str(xdg_steam_path)
1012-
is_flatpak_steam = str(steam_path) == str(flatpak_steam_path)
1013-
1014-
# Adjust the path if the library folder is "~/.local/share/Steam"
1015-
# and we're looking for library folders in
1016-
# "~/.var/app/com.valvesoftware.Steam"
1017-
# This is because ~/.local/share/Steam inside a Steam Flatpak
1018-
# sandbox corresponds to a different location, and we need to
1019-
# adjust for that.
1020-
if is_library_folder_xdg_steam and is_flatpak_steam:
1021-
path = flatpak_steam_path
1022-
1023-
# Steam matches library folders case-insensitively.
1024-
candidates = [
1025-
candidate
1026-
for candidate in path.parent.iterdir()
1027-
if candidate.name.lower() == path.name.lower()
1028-
]
1029-
1030-
logger.debug(
1031-
"Following candidates found for the Steam library path %s: %s",
1032-
path, candidates
1033-
)
1085+
try:
1086+
path = resolve_library_folder(path)
10341087

1035-
if not candidates:
1088+
if path:
1089+
library_folders.append(path)
1090+
except OSError:
10361091
logger.warning(
1037-
"Steam library folder %s in Steam configuration does not "
1038-
"exist",
1039-
path
1092+
"Could not resolve Steam library folder %s", path,
1093+
exc_info=True
10401094
)
10411095
continue
10421096

1043-
# In case of multiple matches, prioritize those that contain
1044-
# a 'steamapps' subdirectory
1045-
candidates.sort(
1046-
key=lambda path: any(
1047-
path.name.lower() == "steamapps"
1048-
for path in path.iterdir()
1049-
),
1050-
reverse=True
1051-
)
1052-
1053-
# In case multiple directories match, pick the first one,
1054-
# log a warning and hope for the best
1055-
if len(candidates) > 1:
1056-
logger.warning(
1057-
"Multiple Steam library folders with name %s were found. "
1058-
"Selecting %s.",
1059-
path, candidates[0]
1060-
)
1061-
1062-
if candidates[0].name != path.name:
1063-
logger.warning(
1064-
"Steam library folder %s in configuration differs from "
1065-
"found path %s. Was this directory renamed?",
1066-
path, candidates[0]
1067-
)
1068-
1069-
path = candidates[0]
1070-
1071-
logger.debug(
1072-
"Found Steam library folder %s. Is Flatpak path: %s, "
1073-
"Is XDG Steam path: %s.",
1074-
path, is_flatpak_steam, is_library_folder_xdg_steam
1075-
)
1076-
1077-
library_folders.append(path)
1078-
10791097
logger.info(
10801098
"Found %d Steam library folders", len(library_folders)
10811099
)
@@ -1091,16 +1109,27 @@ def parse_library_folders(data):
10911109
"directory. Installation may be incomplete or broken."
10921110
) from exc
10931111

1112+
folders_vdf_content = None
10941113
try:
1095-
library_folders = parse_library_folders(folders_vdf_path.read_text())
1114+
folders_vdf_content = folders_vdf_path.read_text()
10961115
except OSError:
1116+
logger.warning(
1117+
"Could not read 'libraryfolders.vdf'. "
1118+
"Maybe no additional Steam library folders haven't been added?",
1119+
exc_info=True
1120+
)
10971121
# libraryfolders.vdf doesn't exist; maybe no Steam library folders
10981122
# are set?
10991123
library_folders = []
1100-
except SyntaxError as exc:
1101-
raise ValueError(
1102-
f"Library folder configuration file {folders_vdf_path} is corrupted"
1103-
) from exc
1124+
1125+
if folders_vdf_content:
1126+
try:
1127+
library_folders = parse_library_folders(folders_vdf_content)
1128+
except SyntaxError as exc:
1129+
raise ValueError(
1130+
f"Library folder configuration file {folders_vdf_path} is "
1131+
f"corrupted"
1132+
) from exc
11041133

11051134
paths = [steam_path] + library_folders
11061135

0 commit comments

Comments
 (0)