feat: implement error classification and handling for AI generation limits

- Added error classification for daily generation cap and concurrency limits in the PromptNode component, improving user feedback during AI image generation failures.
- Enhanced toast notifications to provide specific messages for daily limit and concurrent job errors.
- Introduced internal mutations in the credits module to check abuse limits and track usage, ensuring better resource management and user experience.
- Updated AI error handling logic to categorize and respond to different error types effectively.
This commit is contained in:
Matthias
2026-03-28 11:31:11 +01:00
parent 4b4d784768
commit e5f27d7d29
6 changed files with 193 additions and 12 deletions

View File

@@ -6,6 +6,8 @@ export type AiErrorCategory =
| "network"
| "server"
| "invalid_request"
| "daily_cap"
| "concurrency"
| "unknown";
export interface AiError {
@@ -52,6 +54,12 @@ const CATEGORY_ALIASES: Record<string, AiErrorCategory> = {
invalidrequest: "invalid_request",
bad_request: "invalid_request",
badrequest: "invalid_request",
daily_cap: "daily_cap",
dailycap: "daily_cap",
daily_limit: "daily_cap",
dailylimit: "daily_cap",
concurrency: "concurrency",
concurrent: "concurrency",
};
function normalizeCategory(value: string | undefined): AiErrorCategory | undefined {
@@ -153,6 +161,22 @@ function inferCategoryFromText(text: string): AiErrorCategory {
return "rate_limited";
}
if (
lower.includes("daily_cap") ||
lower.includes("tageslimit erreicht") ||
lower.includes("daily generation limit")
) {
return "daily_cap";
}
if (
lower.includes("concurrency") ||
lower.includes("generierung(en) aktiv") ||
lower.includes("concurrent job limit")
) {
return "concurrency";
}
if (
lower.includes("timeout") ||
lower.includes("timed out") ||
@@ -246,6 +270,20 @@ function defaultsForCategory(category: AiErrorCategory): Omit<AiError, "category
creditsNotCharged: true,
showTopUp: false,
};
case "daily_cap":
return {
message: "Tageslimit erreicht",
retryable: false,
creditsNotCharged: true,
showTopUp: false,
};
case "concurrency":
return {
message: "Generierung bereits aktiv",
retryable: true,
creditsNotCharged: true,
showTopUp: false,
};
case "unknown":
default:
return {