diff --git a/src/nvda_voicemeeter/errors.py b/src/nvda_voicemeeter/errors.py new file mode 100644 index 0000000..a0b7ccc --- /dev/null +++ b/src/nvda_voicemeeter/errors.py @@ -0,0 +1,11 @@ +class NVDAVMError(Exception): + """Base NVDAVM error class""" + + +class NVDAVMCAPIError(NVDAVMError): + """Exception raised when the NVDA C-API returns an error code""" + + def __init__(self, fn_name, code): + self.fn_name = fn_name + self.code = code + super().__init__(f"{self.fn_name} returned {self.code}") diff --git a/src/nvda_voicemeeter/nvda.py b/src/nvda_voicemeeter/nvda.py index 31753ea..bed8246 100644 --- a/src/nvda_voicemeeter/nvda.py +++ b/src/nvda_voicemeeter/nvda.py @@ -1,4 +1,5 @@ from .cdll import libc +from .errors import NVDAVMCAPIError class CBindings: @@ -7,17 +8,20 @@ class CBindings: bind_cancel_speech = libc.nvdaController_cancelSpeech bind_braille_message = libc.nvdaController_brailleMessage - def call(self, fn, *args, ok=(0,)): + def call(self, fn, *args, ok=(0,), ok_exp=None): retval = fn(*args) - if retval not in ok: - raise RuntimeError(f"{fn.__name__} returned {retval}") + if ok_exp is None: + if retval not in ok: + raise NVDAVMCAPIError(fn.__name__, retval) + elif not ok_exp(retval) and retval not in ok: + raise NVDAVMCAPIError(fn.__name__, retval) return retval class Nvda(CBindings): @property def is_running(self): - return self.call(self.bind_test_if_running, ok=(0, 1)) == 0 + return self.call(self.bind_test_if_running, ok_exp=lambda x: x >= 0) == 0 def speak(self, text): self.call(self.bind_speak_text, text)