en un clic
sentry-audio-error-review
// Review unresolved Sentry audio-request issues from the last 24 hours and report any whose exception_type looks mis-categorized against hypertts_addon/errors.py
// Review unresolved Sentry audio-request issues from the last 24 hours and report any whose exception_type looks mis-categorized against hypertts_addon/errors.py
| name | sentry-audio-error-review |
| description | Review unresolved Sentry audio-request issues from the last 24 hours and report any whose exception_type looks mis-categorized against hypertts_addon/errors.py |
| user_invocable | true |
Pull every unresolved HyperTTS audio-request issue from the last 24 hours, judge whether each
issue's exception_type tag matches the actual error evidence, and report any that look
mis-categorized so the service code can be fixed.
Every audio-request exception is captured at hypertts_addon/servicemanager.py:232-246 with the
tag is_audio_request_exception: True. The exception class name is captured in the exception_type
tag and the retryable flag in error_retryable. When a service maps an HTTP response or network
failure to the wrong subclass of ServiceRequestError, retry logic and triage signal both
degrade — that is what this skill catches.
language-tools6170140is:unresolved is_audio_request_exception:True, last 24hhttps://language-tools.sentry.io/issues/<shortId>/Call mcp__sentry__search_issues with:
organizationSlug='language-tools'projectSlugOrId='6170140'query='is:unresolved is_audio_request_exception:True lastSeen:-1d'limit=100The is_audio_request_exception:True tag filter is required — it scopes the search to audio
request failures only (the same filter used in the Sentry UI URL for this triage workflow).
Use lastSeen:-1d, not lastSeen:-24h. The two are semantically equivalent, but the
embedded query-rewriter in the Sentry MCP normalizes the boolean tag value to lowercase
(is_audio_request_exception:true) only on the -24h path, and the lowercase form returns
zero results for this tag. The -1d form is preserved verbatim and works.
Record each issue's shortId, title, and Sentry URL. If zero issues are returned, report "No unresolved audio-request issues in the last 24 hours" and stop.
For each issue, call mcp__sentry__get_sentry_resource with the issue URL. From the latest
event extract:
exception_type tag — the current categorizationerror_retryable tag — the current retryable flagaudio_service tag — which service raised it502 Bad Gateway, requests.exceptions.ConnectionError,
Connection refused, ReadTimeout, Name or service not known)If an issue's tags or event payload don't contain enough evidence to judge the categorization, note it as "insufficient evidence" rather than flagging it.
Use this table — derived from hypertts_addon/errors.py and the mapping logic in
hypertts_addon/cloudlanguagetools.py and hypertts_addon/servicemanager.py — to judge
whether exception_type matches the evidence:
| Evidence in event | Correct exception | Retryable |
|---|---|---|
| HTTP 401 or 403 | ServicePermissionError | False |
| HTTP 404 (audio not found for that text/voice) | AudioNotFoundError | False |
| All priority-mode voices exhausted | AudioNotFoundAnyVoiceError | False |
| Unsupported input (e.g. requested audio format not available) | ServiceInputError | False |
HTTP 429 with Retry-After | RateLimitRetryAfterError | True |
| HTTP 502 / 503 / 504 (no Retry-After) | ServiceGatewayError | True |
requests.exceptions.Timeout / "timed out" / "ReadTimeout" | ServiceTimeoutError | True |
requests.exceptions.ConnectionError / "Connection refused" / "Name or service not known" / "Network is unreachable" | ServiceConnectionError | True |
| Anything else / no clear classifier | UnknownServiceError | True |
Mis-categorization heuristic — flag an issue when any of these hold:
exception_type is the catch-all
UnknownServiceError or the legacy RequestError. A more specific class would have
improved retry logic and grouping.error_retryable tag.exception_type claims (e.g. tagged
ServiceTimeoutError but the trace shows a 502 response).Do not flag an issue when the categorization is correct or when there is insufficient evidence in the event to judge.
Do not flag generic TransientError (or generic PermanentError) when the retryable
disposition is correct. The base TransientError class is an acceptable categorization
for any retryable error — refining it to the specific subclass (ServiceGatewayError,
ServiceTimeoutError, etc.) is a nice-to-have, not a mis-categorization. Concretely, do
not flag these patterns:
TransientError for Gemini TTS error: 504 Deadline Exceeded / <Response [504]>TransientError for VocabAI <Response [504]> with body
"timeout generating TTS audio for Watson: ... Read timed out."TransientError for VocabAI <Response [504]> with body
"timeout generating TTS audio for VocalWare: ... Read timed out."TransientError for VocabAI <Response [504]> with body
"Could not generate audio: CancellationReason.Error Timeout while synthesizing..."Flagging is reserved for cases where the retryable disposition itself is wrong (a
permanent error tagged transient or vice versa), or where the catch-all UnknownServiceError
/ legacy RequestError is hiding a clear specific category.
For each mis-categorized issue, print:
https://language-tools.sentry.io/issues/<shortId>/audio_service tag<exception_type> (error_retryable=<bool>)<class> — and where in the service code the mapping should be
added or fixed (look at the audio_service tag to find the right services/service_<x>.py,
or cloudlanguagetools.py for CLT-routed services)End the report with a one-line summary: Reviewed N issues, M look mis-categorized.
If M == 0, say so explicitly — don't stay silent.
hypertts_addon/errors.py — full exception hierarchyhypertts_addon/servicemanager.py:232-298 — Sentry tagging plus the
requests.exceptions.Timeout / ConnectionError / generic Exception fallback handler
that maps to ServiceTimeoutError / ServiceConnectionError / UnknownServiceErrorhypertts_addon/cloudlanguagetools.py:109-200 — the most thorough HTTP-status-to-error
mapping in the codebase; use it as a model for what good categorization looks like