And the big one - replace the FILE_NOT_FOUND error code with an exception, MissingGameExecutableError, that provides the custom message.

This commit is contained in:
Daniel Johnson 2023-12-27 18:41:08 -05:00
parent bc902394b0
commit 0ce76eed22
27 changed files with 73 additions and 51 deletions

View file

@ -23,6 +23,7 @@ class DirectoryNotFoundError(MisconfigurationError):
if not message and directory:
message = _("The directory {} could not be found").format(directory)
super().__init__(message, *args, **kwarg)
self.directory = directory
class GameConfigError(MisconfigurationError):
@ -69,6 +70,20 @@ class MissingExecutableError(MisconfigurationError):
"""Raised when a program can't be located."""
class MissingGameExecutableError(MissingExecutableError):
"""Raise when a game's executable can't be found is not specified."""
def __init__(self, *args, message=None, filename=None, **kwargs):
if not message:
if filename:
message = _("The file {} could not be found").format(filename)
else:
message = _("This game has no executable set. The install process didn't finish properly.")
super().__init__(message, *args, **kwargs)
self.filename = filename
class EsyncLimitError(Exception):
"""Raised when the ESYNC limit is not set correctly."""

View file

@ -272,15 +272,7 @@ class Game(GObject.Object):
@staticmethod
def get_config_error(gameplay_info):
"""Return a GameConfigError based on the runner's output."""
error = gameplay_info["error"]
if error == "FILE_NOT_FOUND":
filename = gameplay_info["file"]
if filename:
message_text = _("The file {} could not be found").format(filename)
else:
message_text = _("This game has no executable set. The install process didn't finish properly.")
else:
message_text = _("Unhandled error: %s") % gameplay_info["error"]
message_text = _("Unhandled error: %s") % gameplay_info["error"]
return GameConfigError(message_text)
def get_browse_dir(self):

View file

@ -3,7 +3,7 @@ import os.path
from gettext import gettext as _
from lutris.config import LutrisConfig
from lutris.exceptions import MissingBiosError
from lutris.exceptions import MissingBiosError, MissingGameExecutableError
from lutris.runners.runner import Runner
from lutris.util import display, extract, system
@ -141,7 +141,7 @@ class atari800(Runner):
rom = self.game_config.get("main_file") or ""
if not system.path_exists(rom):
return {"error": "FILE_NOT_FOUND", "file": rom}
raise MissingGameExecutableError(filename=rom)
arguments.append(rom)
return {"command": arguments}

View file

@ -1,6 +1,7 @@
"""Dolphin runner"""
from gettext import gettext as _
from lutris.exceptions import MissingGameExecutableError
# Lutris Modules
from lutris.runners.runner import Runner
from lutris.util import system
@ -69,7 +70,7 @@ class dolphin(Runner):
# Retrieve the path to the file
iso = self.game_config.get("main_file") or ""
if not system.path_exists(iso):
return {"error": "FILE_NOT_FOUND", "file": iso}
raise MissingGameExecutableError(filename=iso)
command.extend(["-e", iso])
return {"command": command}

View file

@ -4,6 +4,7 @@ import shlex
from gettext import gettext as _
from lutris import settings
from lutris.exceptions import MissingGameExecutableError
# Lutris Modules
from lutris.runners.commands.dosbox import dosexec, makeconfig # NOQA pylint: disable=unused-import
from lutris.runners.runner import Runner
@ -150,7 +151,7 @@ class dosbox(Runner):
def play(self):
main_file = self.main_file
if not system.path_exists(main_file):
return {"error": "FILE_NOT_FOUND", "file": main_file}
raise MissingGameExecutableError(filename=main_file)
args = shlex.split(self.game_config.get("args") or "")
command = self.get_command()

View file

@ -2,7 +2,7 @@
from gettext import gettext as _
from os import path
from lutris.exceptions import DirectoryNotFoundError, GameConfigError
from lutris.exceptions import DirectoryNotFoundError, GameConfigError, MissingGameExecutableError
# Lutris Modules
from lutris.runners.runner import Runner
@ -571,7 +571,7 @@ class easyrpg(Runner):
if replay_input:
replay_input = path.expanduser(replay_input)
if not path.isfile(replay_input):
return {"error": "FILE_NOT_FOUND", "file": replay_input}
raise MissingGameExecutableError(filename=replay_input)
cmd.extend(("--replay-input", replay_input))
load_game_id = self.game_config.get("load_game_id")

View file

@ -5,7 +5,7 @@ from gettext import gettext as _
# Lutris Modules
from lutris.config import LutrisConfig
from lutris.exceptions import MissingBiosError
from lutris.exceptions import MissingBiosError, MissingGameExecutableError
from lutris.runners.runner import Runner
from lutris.util import system
@ -179,7 +179,7 @@ class hatari(Runner):
raise MissingBiosError()
diska = self.game_config.get("disk-a")
if not system.path_exists(diska):
return {"error": "FILE_NOT_FOUND", "file": diska}
raise MissingGameExecutableError(filename=diska)
params.append("--disk-a")
params.append(diska)

View file

@ -3,6 +3,7 @@ import json
import os
from lutris import settings
from lutris.exceptions import MissingGameExecutableError
from lutris.runners.runner import Runner
from lutris.util import datapath, system
@ -54,7 +55,7 @@ class JsonRunner(Runner):
raise RuntimeError("Unhandled type %s" % option["type"])
main_file = self.game_config.get(self.entry_point_option)
if not system.path_exists(main_file):
return {"error": "FILE_NOT_FOUND", "file": main_file}
raise MissingGameExecutableError(filename=main_file)
arguments.append(main_file)
return {"command": arguments}

View file

@ -2,7 +2,7 @@
import os
from gettext import gettext as _
from lutris.exceptions import MissingBiosError
from lutris.exceptions import MissingBiosError, MissingGameExecutableError
# Lutris Modules
from lutris.runners.runner import Runner
from lutris.util import system
@ -81,7 +81,7 @@ class jzintv(Runner):
raise MissingBiosError()
rom_path = self.game_config.get("main_file") or ""
if not system.path_exists(rom_path):
return {"error": "FILE_NOT_FOUND", "file": rom_path}
raise MissingGameExecutableError(filename=rom_path)
romdir = os.path.dirname(rom_path)
romfile = os.path.basename(rom_path)
arguments += ["--rom-path=%s/" % romdir]

View file

@ -7,7 +7,7 @@ from zipfile import ZipFile
import requests
from lutris import settings
from lutris.exceptions import GameConfigError, UnspecifiedVersionError
from lutris.exceptions import GameConfigError, MissingGameExecutableError, UnspecifiedVersionError
from lutris.runners.runner import Runner
from lutris.util import system
from lutris.util.libretro import RetroConfig
@ -289,6 +289,6 @@ class libretro(Runner):
if not file:
raise GameConfigError(_("No game file specified"))
if not system.path_exists(file):
return {"error": "FILE_NOT_FOUND", "file": file}
raise MissingGameExecutableError(filename=file)
command.append(file)
return {"command": command}

View file

@ -6,7 +6,7 @@ from gettext import gettext as _
from typing import Callable
# Lutris Modules
from lutris.exceptions import GameConfigError, MissingExecutableError
from lutris.exceptions import GameConfigError, MissingExecutableError, MissingGameExecutableError
from lutris.runners.runner import Runner
from lutris.util import system
from lutris.util.strings import split_arguments
@ -158,7 +158,7 @@ class linux(Runner):
exe = self.game_exe
if not exe or not system.path_exists(exe):
return {"error": "FILE_NOT_FOUND", "file": exe}
raise MissingGameExecutableError(filename=exe)
# Quit if the file is not executable
mode = os.stat(exe).st_mode

View file

@ -2,6 +2,7 @@
import subprocess
from gettext import gettext as _
from lutris.exceptions import MissingGameExecutableError
# Lutris Modules
from lutris.runners.runner import Runner
from lutris.util import system
@ -521,7 +522,7 @@ class mednafen(Runner):
options.append(control)
if not system.path_exists(rom):
return {"error": "FILE_NOT_FOUND", "file": rom}
raise MissingGameExecutableError(filename=rom)
command = self.get_command()
for option in options:

View file

@ -4,6 +4,7 @@ from gettext import gettext as _
# Lutris Modules
from lutris import settings
from lutris.exceptions import MissingGameExecutableError
from lutris.runners.runner import Runner
from lutris.util import system
@ -52,6 +53,6 @@ class mupen64plus(Runner):
arguments.append("--windowed")
rom = self.game_config.get("main_file") or ""
if not system.path_exists(rom):
return {"error": "FILE_NOT_FOUND", "file": rom}
raise MissingGameExecutableError(filename=rom)
arguments.append(rom)
return {"command": arguments}

View file

@ -2,6 +2,7 @@
import os
from gettext import gettext as _
from lutris.exceptions import MissingGameExecutableError
# Lutris Modules
from lutris.runners.runner import Runner
from lutris.util import system
@ -122,7 +123,7 @@ class o2em(Runner):
arguments.append("-s2=%s" % self.runner_config["controller2"])
rom_path = self.game_config.get("main_file") or ""
if not system.path_exists(rom_path):
return {"error": "FILE_NOT_FOUND", "file": rom_path}
raise MissingGameExecutableError(filename=rom_path)
romdir = os.path.dirname(rom_path)
romfile = os.path.basename(rom_path)
arguments.append("-romdir=%s/" % romdir)

View file

@ -1,6 +1,7 @@
# Standard Library
from gettext import gettext as _
from lutris.exceptions import MissingGameExecutableError
# Lutris Modules
from lutris.runners.runner import Runner
from lutris.util import system
@ -23,5 +24,5 @@ class openmsx(Runner):
def play(self):
rom = self.game_config.get("main_file") or ""
if not system.path_exists(rom):
return {"error": "FILE_NOT_FOUND", "file": rom}
raise MissingGameExecutableError(filename=rom)
return {"command": self.get_command() + [rom]}

View file

@ -1,6 +1,7 @@
# Standard Library
from gettext import gettext as _
from lutris.exceptions import MissingGameExecutableError
# Lutris Modules
from lutris.runners.runner import Runner
from lutris.util import system
@ -40,7 +41,7 @@ class osmose(Runner):
arguments = self.get_command()
rom = self.game_config.get("main_file") or ""
if not system.path_exists(rom):
return {"error": "FILE_NOT_FOUND", "file": rom}
raise MissingGameExecutableError(filename=rom)
arguments.append(rom)
if self.runner_config.get("fullscreen"):
arguments.append("-fs")

View file

@ -1,6 +1,7 @@
# Standard Library
from gettext import gettext as _
from lutris.exceptions import MissingGameExecutableError
# Lutris Modules
from lutris.runners.runner import Runner
from lutris.util import system
@ -56,6 +57,6 @@ class pcsx2(Runner):
iso = self.game_config.get("main_file") or ""
if not system.path_exists(iso):
return {"error": "FILE_NOT_FOUND", "file": iso}
raise MissingGameExecutableError(filename=iso)
arguments.append(iso)
return {"command": arguments}

View file

@ -8,6 +8,7 @@ from time import sleep
from lutris import settings
from lutris.database.games import get_game_by_field
from lutris.exceptions import MissingGameExecutableError
from lutris.runners.runner import Runner
from lutris.util import system
from lutris.util.downloader import Downloader
@ -210,7 +211,7 @@ class pico8(Runner):
command.append("-run")
cartPath = self.cart_path
if not os.path.exists(cartPath):
return {"error": "FILE_NOT_FOUND", "file": cartPath}
raise MissingGameExecutableError(filename=cartPath)
command.append(cartPath)
else:

View file

@ -1,6 +1,7 @@
# Standard Library
from gettext import gettext as _
from lutris.exceptions import MissingGameExecutableError
# Lutris Modules
from lutris.runners.runner import Runner
from lutris.util import system
@ -34,6 +35,6 @@ class rpcs3(Runner):
eboot = self.game_config.get("main_file") or ""
if not system.path_exists(eboot):
return {"error": "FILE_NOT_FOUND", "file": eboot}
raise MissingGameExecutableError(filename=eboot)
arguments.append(eboot)
return {"command": arguments}

View file

@ -3,6 +3,7 @@ import os
from gettext import gettext as _
from shutil import copyfile
from lutris.exceptions import MissingGameExecutableError
from lutris.runners.runner import Runner
from lutris.util import system
from lutris.util.log import logger
@ -53,7 +54,7 @@ class ryujinx(Runner):
arguments = self.get_command()
rom = self.game_config.get("main_file") or ""
if not system.path_exists(rom):
return {"error": "FILE_NOT_FOUND", "file": rom}
raise MissingGameExecutableError(filename=rom)
arguments.append(rom)
return {"command": arguments}

View file

@ -6,6 +6,7 @@ from gettext import gettext as _
# Lutris Modules
from lutris import settings
from lutris.exceptions import MissingGameExecutableError
from lutris.runners.runner import Runner
from lutris.util import system
from lutris.util.log import logger
@ -83,5 +84,5 @@ class snes9x(Runner):
rom = self.game_config.get("main_file") or ""
if not system.path_exists(rom):
return {"error": "FILE_NOT_FOUND", "file": rom}
raise MissingGameExecutableError(filename=rom)
return {"command": self.get_command() + [rom]}

View file

@ -3,7 +3,7 @@ import os
from gettext import gettext as _
from lutris.command import MonitoredCommand
from lutris.exceptions import UnavailableRunnerError
from lutris.exceptions import MissingGameExecutableError, UnavailableRunnerError
from lutris.runners import NonInstallableRunnerError
from lutris.runners.runner import Runner
from lutris.util import linux, system
@ -217,7 +217,7 @@ class steam(Runner):
if self.game_config.get("run_without_steam") and binary_path:
# Start without steam
if not system.path_exists(binary_path):
return {"error": "FILE_NOT_FOUND", "file": binary_path}
raise MissingGameExecutableError(filename=binary_path)
command = [binary_path]
else:
# Start through steam

View file

@ -4,7 +4,7 @@ from gettext import gettext as _
# Lutris Modules
from lutris import settings
from lutris.exceptions import GameConfigError, MisconfigurationError, MissingExecutableError
from lutris.exceptions import GameConfigError, MisconfigurationError, MissingExecutableError, MissingGameExecutableError
from lutris.runners.runner import Runner
from lutris.util import system
from lutris.util.log import logger
@ -32,12 +32,9 @@ class vice(Runner):
]
game_options = [
{
"option":
"main_file",
"type":
"file",
"label":
_("ROM file"),
"option": "main_file",
"type": "file",
"label": _("ROM file"),
"help": _(
"The game data, commonly called a ROM image.\n"
"Supported formats: X64, D64, G64, P64, D67, D71, D81, "
@ -198,7 +195,7 @@ class vice(Runner):
if not rom:
raise GameConfigError(_("No rom provided"))
if not system.path_exists(rom):
return {"error": "FILE_NOT_FOUND", "file": rom}
raise MissingGameExecutableError(filename=rom)
params = [self.get_executable(machine)]
rom_dir = os.path.dirname(rom)

View file

@ -10,7 +10,8 @@ from lutris.api import format_runner_version, get_default_runner_version_info
from lutris.config import LutrisConfig
from lutris.database.games import get_game_by_field
from lutris.exceptions import (
EsyncLimitError, FsyncUnsupportedError, MisconfigurationError, MissingExecutableError, UnspecifiedVersionError
EsyncLimitError, FsyncUnsupportedError, MisconfigurationError, MissingExecutableError, MissingGameExecutableError,
UnspecifiedVersionError
)
from lutris.game import Game
from lutris.gui.dialogs import FileDialog
@ -1143,7 +1144,7 @@ class wine(Runner):
launch_info["env"]["WINE_LARGE_ADDRESS_AWARE"] = "1"
if not game_exe or not system.path_exists(game_exe):
return {"error": "FILE_NOT_FOUND", "file": game_exe}
raise MissingGameExecutableError(filename=game_exe)
if launch_info["env"].get("WINEESYNC") == "1":
limit_set = is_esync_limit_set()

View file

@ -1,5 +1,6 @@
from gettext import gettext as _
from lutris.exceptions import MissingGameExecutableError
from lutris.runners.runner import Runner
from lutris.util import system
@ -41,6 +42,6 @@ class xemu(Runner):
iso = self.game_config.get("main_file") or ""
if not system.path_exists(iso):
return {"error": "FILE_NOT_FOUND", "file": iso}
raise MissingGameExecutableError(filename=iso)
arguments += ["-dvd_path", iso]
return {"command": arguments}

View file

@ -3,6 +3,7 @@ import os
from gettext import gettext as _
from shutil import copyfile
from lutris.exceptions import MissingGameExecutableError
from lutris.runners.runner import Runner
from lutris.util import system
from lutris.util.log import logger
@ -48,7 +49,7 @@ class yuzu(Runner):
@property
def yuzu_data_dir(self):
"""Return dir where Yuzu files lie."""
candidates = ("~/.local/share/yuzu", )
candidates = ("~/.local/share/yuzu",)
for candidate in candidates:
path = system.fix_path_case(os.path.join(os.path.expanduser(candidate), "nand"))
if system.path_exists(path):
@ -64,7 +65,7 @@ class yuzu(Runner):
rom = self.game_config.get("main_file") or ""
if not system.path_exists(rom):
return {"error": "FILE_NOT_FOUND", "file": rom}
raise MissingGameExecutableError(filename=rom)
arguments += ["-g", rom]
return {"command": arguments}

View file

@ -1,6 +1,7 @@
import unittest
from unittest.mock import MagicMock, patch
from lutris.exceptions import MissingGameExecutableError
from lutris.runners.pcsx2 import pcsx2
@ -19,8 +20,9 @@ class TestPCSX2Runner(unittest.TestCase):
mock_config.game_config = {'main_file': main_file}
mock_config.runner_config = MagicMock()
self.runner.config = mock_config
expected = {'error': 'FILE_NOT_FOUND', 'file': main_file}
self.assertEqual(self.runner.play(), expected)
with self.assertRaises(MissingGameExecutableError) as cm:
self.runner.play()
self.assertEqual(cm.exception.filename, main_file)
@patch('lutris.util.system.path_exists')
@patch('os.path.isfile')