Skip to content

Raise real exceptions instead of strings in the runtime Python bindings - #3524

Open
LeonardNJU wants to merge 1 commit into
modelscope:mainfrom
LeonardNJU:fix/raise-string-masks-real-exception
Open

Raise real exceptions instead of strings in the runtime Python bindings#3524
LeonardNJU wants to merge 1 commit into
modelscope:mainfrom
LeonardNJU:fix/raise-string-masks-real-exception

Conversation

@LeonardNJU

Copy link
Copy Markdown

Fixes #3523.

raise "some message" is invalid in Python 3 — a str is not an exception. The
interpreter discards the intended message and raises

TypeError: exceptions must derive from BaseException

instead. Paired with the surrounding bare except:, the original cause is lost as well,
so the user is told to install a package they may already have while the real failure is
invisible.

What this looked like in practice

funasr was installed. The import failed on a missing transitive dependency:

File ".../funasr/utils/load_utils.py", line 9, in <module>
    import torchaudio
ModuleNotFoundError: No module named 'torchaudio'

What I saw:

File ".../funasr_onnx/sensevoice_bin.py", line 66, in __init__
    raise "You are exporting onnx, please install funasr and try it again..."
TypeError: exceptions must derive from BaseException

The message pointed at the wrong package, and the traceback pointed at the wrong error.
Diagnosing it meant reading the library source and reproducing the import by hand. I hit
the same wall a second time on onnxscript (required by newer torch.onnx), and a third
time when loading from a local path — the model_dir branch fires on any failure, so a
mistyped path also surfaced as TypeError.

The change

All 30 occurrences under runtime/python (7 files, both funasr_onnx and
funasr_torch):

# before
try:
    from funasr import AutoModel
except:
    raise "You are exporting onnx, please install funasr and try it again. ..."

# after
try:
    from funasr import AutoModel
except ImportError as e:
    raise ImportError(
        "You are exporting onnx, please install funasr and try it again. ..."
    ) from e
  • guarded imports → except ImportError as e: / raise ImportError(...) from e
  • everything else → except Exception as e: / raise RuntimeError(...) from e

from e preserves the original traceback, which is the point — a missing torchaudio
now stays visible under the friendly message. Narrowing the bare except: also stops
unrelated failures from being reported as a missing package.

Messages are unchanged. The only behavioural difference is the exception type, which
previously could not be caught by anything anyway.

Verification

  • raise " no longer appears anywhere under runtime/python
  • every changed file passes python -m py_compile
  • chaining behaves as intended:
外层信息: please install funasr: pip3 install -U funasr
真实原因: No module named 'nonexistent_module_xyz'

I deliberately did not run black over these files. It reformats unrelated code in
them (the tree is not currently black-clean), which would have buried a 140-line fix in a
280-line diff. The new code follows the project's 100-column style by hand. Happy to run
the formatter if you would rather have it.

Two occurrences outside runtime/python are left alone as out of scope:
funasr/models/qwen3_asr/model.py and funasr/download/runtime_sdk_download_tool.py.

Context: found while building a local-ASR adapter for Jitsi Meet
(https://github.com/LeonardNJU/jitsi-local-asr) that runs SenseVoice and streaming
Paraformer via funasr_onnx on an ARM box.

`raise "some message"` is invalid in Python 3 — a str is not an exception — so
the interpreter discards the message and raises

    TypeError: exceptions must derive from BaseException

instead. Paired with a bare `except:`, the original cause is lost too, and the
user is told to install something they may already have.

Concretely: funasr was installed, but importing it failed on a missing
torchaudio. The message said 'please install funasr', the traceback said
TypeError, and the actual ModuleNotFoundError was nowhere to be seen.

This converts all 30 occurrences under runtime/python to real exceptions:

  - guarded imports        -> except ImportError as e: raise ImportError(...) from e
  - everything else        -> except Exception as e:  raise RuntimeError(...) from e

`from e` keeps the original traceback, so a missing transitive dependency stays
visible. Narrowing the bare `except:` also stops unrelated failures from being
reported as a missing package — the model_dir branch in particular fired for any
failure, so a mistyped path also surfaced as TypeError.

Messages are unchanged. No behaviour changes beyond the exception type.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

funasr_onnx: bare raise "string" masks the real exception (TypeError: exceptions must derive from BaseException)

1 participant