Skip to content

infrahubctl: typer.Exit leaks raw traceback on schema load failure #1047

@minitriga

Description

@minitriga

Component

infrahubctl

Infrahub SDK version

v1.20.1

Current Behavior

When infrahubctl schema load receives an error response from the server, it
correctly prints the human-readable error, then exposes a raw Python traceback:

Unable to load the schema:
  Unable to find the schema 'TemplateDcimDevice' in the registry
Error: 1
Traceback (most recent call last):
  File ".../infrahub_sdk/ctl/utils.py", line 93, in async_wrapper
    return await func(*args, **kwargs)
  File ".../infrahub_sdk/ctl/schema.py", line 201, in load
    raise typer.Exit(1)
typer._click.exceptions.Exit: 1

The Error: 1 line and the traceback below it are implementation noise — the
useful message has already been printed above.

Root cause: typer.Exit inherits from BaseException, not Exception. The
catch_exception decorator in utils.py only catches (Error, Exception), so
typer.Exit propagates uncaught through async_wrapper. Because typer.Exit is
not SystemExit, Python's default handler prints the full traceback instead of
silently exiting.

Expected Behavior

After printing the human-readable error, the command exits with code 1 and no
traceback. The terminal output should be:

Unable to load the schema:
  Unable to find the schema 'TemplateDcimDevice' in the registry

Steps to Reproduce

  1. Have a running Infrahub instance
  2. Load a schema that triggers any server-side validation error (e.g. a
    relationship peer that doesn't exist)
  3. Run infrahubctl schema load <schema-dir>
  4. Observe the traceback after the error message

Additional Information

The fix belongs in AsyncTyper or catch_exception — either intercept
typer.Exit / BaseException and call sys.exit(code), or exclude
typer.Exit from the catch clause so Typer's own machinery handles it cleanly.

Related: opsmill/infrahub#9364 (the server-side error that surfaced this UX
issue)

Metadata

Metadata

Assignees

No one assigned

    Labels

    state/need-triageThis issue needs to be triagedtype/bugSomething isn't working as expected

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions