feat: unify structured error output

This commit is contained in:
jackwener
2026-03-10 21:18:38 +08:00
parent 9b7bdf3b06
commit 4c2c02efd5
3 changed files with 46 additions and 0 deletions

View File

@@ -52,6 +52,7 @@ from .formatter import (
from .models import UserProfile
from .output import (
default_structured_format,
emit_error,
emit_structured,
error_payload,
structured_output_options,
@@ -144,6 +145,8 @@ def _get_client_for_output(config=None, quiet=False):
def _exit_with_error(exc):
# type: (RuntimeError) -> None
if emit_error("api_error", str(exc)):
sys.exit(1)
console.print("[red]❌ %s[/red]" % exc)
sys.exit(1)

View File

@@ -99,3 +99,30 @@ def _normalize_success_payload(data: Any) -> Any:
if isinstance(data, dict) and data.get("schema_version") == _SCHEMA_VERSION and "ok" in data:
return data
return success_payload(data)
def emit_error(
code: str,
message: str,
*,
as_json: bool | None = None,
as_yaml: bool | None = None,
details: Any | None = None,
) -> bool:
"""Emit a structured error when the active output mode is machine-readable."""
if as_json is None or as_yaml is None:
ctx = click.get_current_context(silent=True)
params = ctx.params if ctx is not None else {}
as_json = bool(params.get("as_json", False)) if as_json is None else as_json
as_yaml = bool(params.get("as_yaml", False)) if as_yaml is None else as_yaml
fmt = default_structured_format(as_json=bool(as_json), as_yaml=bool(as_yaml))
if fmt is None:
return False
payload = error_payload(code, message, details=details)
if fmt == "json":
click.echo(json.dumps(payload, ensure_ascii=False, indent=2))
else:
click.echo(yaml.safe_dump(payload, allow_unicode=True, sort_keys=False, default_flow_style=False))
return True