AQIT
0.1.0
Toggle main menu visibility
Loading...
Searching...
No Matches
user_errors.py
Go to the documentation of this file.
1
# Copyright (c) 2025-present Aquin Labs Private Limited. All Rights Reserved.
2
"""User-facing CLI errors — no raw HTTP tracebacks unless AQUIN_DEBUG=1."""
3
from
__future__
import
annotations
4
5
import
json
6
import
os
7
import
re
8
import
sys
9
from
typing
import
Any
10
11
_URL_RE = re.compile(
r"https?://[^\s'\"<>]+"
)
12
13
14
def
debug_enabled
() -> bool:
15
return
os.environ.get(
"AQUIN_DEBUG"
,
""
).strip().lower()
in
(
"1"
,
"true"
,
"yes"
)
16
17
18
def
log_debug
(label: str, detail: Any) ->
None
:
19
if
debug_enabled
():
20
print(f
"[debug/{label}] {detail}"
, file=sys.stderr)
21
22
23
def
_scrub_urls
(text: str) -> str:
24
return
_URL_RE.sub(
"Aquin cloud"
, text)
25
26
27
def
sanitize_error_string
(text: str) -> str:
28
"""Turn raw API/library strings into short user-facing messages."""
29
if
not
text:
30
return
"Something went wrong. Try again."
31
32
s =
_scrub_urls
(str(text).strip())
33
low = s.lower()
34
35
if
s.startswith((
"Could not "
,
"Cannot "
,
"No API key"
,
"Not logged in"
,
"Run:"
,
"Usage:"
)):
36
return
s
37
if
"run: aquin login"
in
low
or
"aquin.app/profile"
in
low:
38
return
s
39
40
if
"401"
in
s
or
"unauthorized"
in
low:
41
return
"Authentication failed. Set HF_TOKEN / OPENAI_API_KEY if this call needs cloud credentials."
42
if
"token revoked"
in
low
or
"revoked_at"
in
low:
43
return
"Cloud token rejected. Use a local path or set the required env token."
44
if
"403"
in
s
or
"forbidden"
in
low:
45
return
"Access denied for this resource."
46
if
"404"
in
s
and
(
"sae"
in
low
or
"not found"
in
low):
47
return
(
48
"SAE not found in the Aquin library. Try aquin load sae <model-l{n}> "
49
"or aquin load sae --path <file.pt>\n"
50
"Some models (gpt2-small, pythia-70m) pull SAE weights from Hugging Face instead."
51
)
52
if
"404"
in
s
or
"not found"
in
low:
53
return
"Not found."
54
if
"503"
in
s
or
"not configured on"
in
low:
55
return
"This feature is temporarily unavailable. Try again later."
56
if
any(x
in
low
for
x
in
(
"connection"
,
"timeout"
,
"network"
,
"could not reach"
,
"name resolution"
)):
57
return
"Could not reach Aquin. Check your internet connection."
58
if
isinstance(text, json.JSONDecodeError)
or
"jsondecode"
in
low
or
"extra data"
in
low:
59
return
"Could not read the server response. Try again."
60
if
"hugging face access via aquin proxy"
in
low:
61
return
s.split(
"\n"
)[0]
if
"\n"
in
s
else
s
62
if
any(x
in
low
for
x
in
(
"zip archive"
,
"central directory"
,
"pytorchstreamreader"
)):
63
return
(
64
"SAE checkpoint file is corrupted or incomplete. "
65
"Delete it under ~/.aquin/sae/ and run: aquin load sae <model>-l<layer>"
66
)
67
if
any(x
in
low
for
x
in
(
"out of memory"
,
"cuda out of memory"
)):
68
return
s
if
len(s) <= 500
else
s[:500] +
"…"
69
if
any(x
in
low
for
x
in
(
"huggingface"
,
"gated repo"
,
"hf hub"
,
"gated"
)):
70
return
(
71
"Could not download from Hugging Face. "
72
"Set HF_TOKEN for gated models, or use a public checkpoint."
73
)
74
if
"client error"
in
low
or
"httperror"
in
low
or
"for url"
in
low:
75
return
"Request failed. Check network / credentials and try aquin status."
76
if
" failed:"
in
low:
77
_, tail = re.split(
r"\bfailed:\s*"
, s, maxsplit=1, flags=re.I)
78
if
tail:
79
return
sanitize_error_string
(tail.strip())
80
81
if
len(s) > 180
and
not
debug_enabled
():
82
return
"Something went wrong. Try again. (Set AQUIN_DEBUG=1 for details)"
83
return
s
84
85
86
def
friendly_message
(exc: BaseException) -> str:
87
if
isinstance(exc, KeyboardInterrupt):
88
raise
exc
89
90
try
:
91
import
httpx
92
93
if
isinstance(exc, httpx.HTTPStatusError):
94
code = exc.response.status_code
if
exc.response
is
not
None
else
0
95
if
code
in
(401, 403):
96
return
"Authentication failed. Set the required env token (e.g. HF_TOKEN)."
97
if
code == 404:
98
return
"Not found."
99
if
code >= 500:
100
return
"Remote service is having trouble. Try again shortly."
101
return
sanitize_error_string
(str(exc))
102
except
ImportError:
103
pass
104
105
try
:
106
import
requests
107
from
requests.exceptions
import
HTTPError, ConnectionError, Timeout
108
109
if
isinstance(exc, HTTPError):
110
code = exc.response.status_code
if
exc.response
is
not
None
else
0
111
if
code
in
(401, 403):
112
return
"Authentication failed. Set the required env token (e.g. HF_TOKEN)."
113
if
code == 404:
114
return
sanitize_error_string
(str(exc))
115
if
code >= 500:
116
return
"Remote service is having trouble. Try again shortly."
117
return
sanitize_error_string
(str(exc))
118
if
isinstance(exc, (ConnectionError, Timeout)):
119
return
"Could not reach remote service. Check your internet connection."
120
except
ImportError:
121
pass
122
123
if
isinstance(exc, FileNotFoundError):
124
msg = str(exc).strip()
125
if
msg
and
(
126
"sae"
in
msg.lower()
127
or
"layer"
in
msg.lower()
128
or
"dictionary"
in
msg.lower()
129
or
"\n"
in
msg
130
):
131
return
msg
132
return
"File not found. Check the path and try again."
133
if
isinstance(exc, json.JSONDecodeError):
134
return
"Could not read JSON input. Check the file format."
135
if
isinstance(exc, NotImplementedError):
136
msg = str(exc).strip()
137
if
msg
and
(
"not yet ported"
in
msg.lower()
or
"not available in"
in
msg.lower()):
138
return
msg
139
if
msg
and
debug_enabled
():
140
return
f
"This command is not available yet. ({msg})"
141
if
msg
and
len(msg) < 120:
142
return
msg
143
return
"This command is not available yet."
144
if
isinstance(exc, ValueError):
145
msg = str(exc).strip()
146
if
msg
and
not
msg.startswith(
"HTTP"
):
147
if
"corrupt"
in
msg.lower()
or
"re-download"
in
msg.lower()
or
len(msg) < 400:
148
return
msg
149
if
isinstance(exc, RuntimeError):
150
from
aquin.compute.torch_io
import
is_corrupt_pytorch_zip
151
152
msg = str(exc).strip()
153
if
msg
and
is_corrupt_pytorch_zip(exc):
154
return
(
155
"SAE checkpoint file is corrupted or incomplete. "
156
"Delete it under ~/.aquin/sae/ and run: aquin load sae <model>-l<layer>"
157
)
158
159
msg = str(exc).strip()
160
if
msg:
161
return
sanitize_error_string
(msg)
162
return
"Something went wrong. Try again."
163
164
165
def
die
(
166
message: str |
None
=
None
,
167
*,
168
exc: BaseException |
None
=
None
,
169
code: int = 1,
170
label: str =
"aquin"
,
171
) ->
None
:
172
if
exc
is
not
None
:
173
log_debug
(label, exc)
174
text = message
or
friendly_message
(exc)
175
else
:
176
text = message
or
"Something went wrong. Try again."
177
print(text, file=sys.stderr)
178
raise
SystemExit(code)
179
180
181
def
exit_on
(exc: BaseException, *, label: str =
"aquin"
, code: int = 1) ->
None
:
182
die
(exc=exc, label=label, code=code)
aquin.compute.torch_io
Definition
torch_io.py:1
aquin.user_errors.exit_on
None exit_on(BaseException exc, *, str label="aquin", int code=1)
Definition
user_errors.py:185
aquin.user_errors.friendly_message
str friendly_message(BaseException exc)
Definition
user_errors.py:90
aquin.user_errors._scrub_urls
str _scrub_urls(str text)
Definition
user_errors.py:27
aquin.user_errors.debug_enabled
bool debug_enabled()
Definition
user_errors.py:18
aquin.user_errors.die
None die(str|None message=None, *, BaseException|None exc=None, int code=1, str label="aquin")
Definition
user_errors.py:175
aquin.user_errors.sanitize_error_string
str sanitize_error_string(str text)
Definition
user_errors.py:31
aquin.user_errors.log_debug
None log_debug(str label, Any detail)
Definition
user_errors.py:22
aquin
user_errors.py
AQIT · Aquin Labs Private Limited · Apache 2.0 · Generated by
1.18.0