feat(ai-chat): surface the real cause in the error banner
The AI chat error banner always showed a generic "Something went wrong"
with no reason. The server already forwards the provider cause into the
stream (e.g. "Cannot connect to API: read ECONNRESET"), but the client
hid it behind a static heading.
- describeChatError now returns { title, detail }: a short heading naming
the cause category plus a one-line explanation.
- Add classifyProviderError: maps connection reset, timeout, rate limit,
context-window overflow, quota and auth failures to clear categories;
the 403/503 gating responses are preserved; unknown errors fall back to
the verbatim provider text.
- Match HTTP status codes only as the leading token and textual signatures
only against the message head (before "| response body:"), so a number
or phrase in the response-body snippet never mislabels the cause.
- Use the new {title, detail} in all three banners: chat-thread,
share-ai-widget and the persisted-error banner in message-item.
- Cover the classifier with 20 unit tests (categories + regressions).
This commit is contained in:
@@ -88,6 +88,10 @@ export default function ShareAiWidget({
|
||||
|
||||
const isStreaming = status === "submitted" || status === "streaming";
|
||||
|
||||
// Same classified-error banner as the internal chat: name the cause instead of a
|
||||
// generic heading.
|
||||
const errorView = error ? describeChatError(error.message ?? "", t) : null;
|
||||
|
||||
const handleSend = () => {
|
||||
const text = input.trim();
|
||||
if (!text || isStreaming) return;
|
||||
@@ -173,18 +177,18 @@ export default function ShareAiWidget({
|
||||
/>
|
||||
</Box>
|
||||
|
||||
{error && (
|
||||
{errorView && (
|
||||
<Alert
|
||||
variant="light"
|
||||
color="red"
|
||||
icon={<IconAlertTriangle size={16} />}
|
||||
mx="sm"
|
||||
mb="xs"
|
||||
title={t("Something went wrong")}
|
||||
title={errorView.title}
|
||||
>
|
||||
{/* Surface the real cause (provider/gating message) instead of a
|
||||
{/* Surface the real cause (provider/gating category) instead of a
|
||||
generic line — same helper the internal chat uses. */}
|
||||
{describeChatError(error.message ?? "", t)}
|
||||
{errorView.detail}
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user