feat: add AI chat error handling for billing and API key errors (#16797)
## Summary This PR adds user-friendly error handling for AI chat features, specifically for **billing credits exhausted** and **API key not configured** errors. ## Changes ### Backend - Added `BILLING_CREDITS_EXHAUSTED` exception code with 402 status - Added `API_KEY_NOT_CONFIGURED` exception code with 503 status - Added billing check before AI chat streaming in `agent-chat.controller.ts` - Added error code to HTTP exception response body for frontend error type detection - Created `AgentRestApiExceptionFilter` for agent-specific errors ### Frontend - Created `AIChatBanner` - reusable banner component for error/warning messages - Created `AIChatCreditsExhaustedMessage` - shows upgrade prompts based on user permissions - Created `AIChatApiKeyNotConfiguredMessage` - shows configuration guidance with docs link - Created `AIChatErrorRenderer` - encapsulates error type switching logic (fixes nested ternary) - Created `AIChatStandaloneError` - displays errors when there are no messages - Split `aiChatErrorUtils.ts` into separate files (1 export per file): - `AIChatErrorCode.ts` - `extractErrorCode.ts` - `isAIChatErrorOfType.ts` - `isBillingCreditsExhaustedError.ts` - `isApiKeyNotConfiguredError.ts` - Added comprehensive test coverage (27 tests) ### Other - Updated trial period banner messaging ## Testing - All lint checks pass - All 27 new tests pass - TypeScript typecheck passes
This commit is contained in:
@@ -30,6 +30,7 @@ export enum BillingExceptionCode {
|
||||
BILLING_PRICE_INVALID = 'BILLING_PRICE_INVALID',
|
||||
BILLING_SUBSCRIPTION_PHASE_NOT_FOUND = 'BILLING_SUBSCRIPTION_PHASE_NOT_FOUND',
|
||||
BILLING_TOO_MUCH_SUBSCRIPTIONS_FOUND = 'BILLING_TOO_MUCH_SUBSCRIPTIONS_FOUND',
|
||||
BILLING_CREDITS_EXHAUSTED = 'BILLING_CREDITS_EXHAUSTED',
|
||||
}
|
||||
|
||||
const billingExceptionUserFriendlyMessages: Record<
|
||||
@@ -60,6 +61,7 @@ const billingExceptionUserFriendlyMessages: Record<
|
||||
[BillingExceptionCode.BILLING_PRICE_INVALID]: msg`Invalid price.`,
|
||||
[BillingExceptionCode.BILLING_SUBSCRIPTION_PHASE_NOT_FOUND]: msg`Subscription phase not found.`,
|
||||
[BillingExceptionCode.BILLING_TOO_MUCH_SUBSCRIPTIONS_FOUND]: msg`Multiple subscriptions found where one was expected.`,
|
||||
[BillingExceptionCode.BILLING_CREDITS_EXHAUSTED]: msg`You have exhausted your credits. Please upgrade your plan to continue.`,
|
||||
};
|
||||
|
||||
export class BillingException extends CustomException<BillingExceptionCode> {
|
||||
|
||||
+6
@@ -66,6 +66,12 @@ export class BillingRestApiExceptionFilter implements ExceptionFilter {
|
||||
response,
|
||||
400,
|
||||
);
|
||||
case BillingExceptionCode.BILLING_CREDITS_EXHAUSTED:
|
||||
return this.httpExceptionHandlerService.handleError(
|
||||
exception,
|
||||
response,
|
||||
402,
|
||||
);
|
||||
default:
|
||||
return this.httpExceptionHandlerService.handleError(
|
||||
exception,
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { isDefined } from 'class-validator';
|
||||
import { Repository } from 'typeorm';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { type Repository } from 'typeorm';
|
||||
|
||||
import { BillingSubscriptionEntity } from 'src/engine/core-modules/billing/entities/billing-subscription.entity';
|
||||
import { type BillingEntitlementKey } from 'src/engine/core-modules/billing/enums/billing-entitlement-key.enum';
|
||||
import { BillingProductKey } from 'src/engine/core-modules/billing/enums/billing-product-key.enum';
|
||||
import { type BillingProductKey } from 'src/engine/core-modules/billing/enums/billing-product-key.enum';
|
||||
import { SubscriptionStatus } from 'src/engine/core-modules/billing/enums/billing-subscription-status.enum';
|
||||
import { BillingProductService } from 'src/engine/core-modules/billing/services/billing-product.service';
|
||||
import { BillingSubscriptionService } from 'src/engine/core-modules/billing/services/billing-subscription.service';
|
||||
|
||||
Reference in New Issue
Block a user