Просмотр исходного кода

All errors with delta.event of 'thread.run.failed' are returned to the client

Shun Miyazawa 1 год назад
Родитель
Сommit
1fc0cffb94

+ 6 - 1
apps/app/src/features/openai/interfaces/message-error.ts

@@ -3,7 +3,12 @@ export const MessageErrorCode = {
 } as const;
 } as const;
 
 
 export const StreamErrorCode = {
 export const StreamErrorCode = {
-  RATE_LIMIT_EXCEEDED: 'rate_limit_exceeded',
+  BUDGET_EXCEEDED: 'budget-exceeded',
 } as const;
 } as const;
 
 
 export type StreamErrorCode = typeof StreamErrorCode[keyof typeof StreamErrorCode];
 export type StreamErrorCode = typeof StreamErrorCode[keyof typeof StreamErrorCode];
+
+export const OpenaiStreamErrorMessage = {
+  // eslint-disable-next-line max-len
+  BUDGET_EXCEEDED: 'You exceeded your current quota, please check your plan and billing details. For more information on this error, read the docs: https://platform.openai.com/docs/guides/error-codes/api-errors.',
+} as const;

+ 14 - 5
apps/app/src/features/openai/server/routes/message.ts

@@ -11,7 +11,7 @@ import { apiV3FormValidator } from '~/server/middlewares/apiv3-form-validator';
 import type { ApiV3Response } from '~/server/routes/apiv3/interfaces/apiv3-response';
 import type { ApiV3Response } from '~/server/routes/apiv3/interfaces/apiv3-response';
 import loggerFactory from '~/utils/logger';
 import loggerFactory from '~/utils/logger';
 
 
-import { MessageErrorCode, StreamErrorCode } from '../../interfaces/message-error';
+import { MessageErrorCode, StreamErrorCode, OpenaiStreamErrorMessage } from '../../interfaces/message-error';
 import { openaiClient } from '../services';
 import { openaiClient } from '../services';
 
 
 import { certifyAiService } from './middlewares/certify-ai-service';
 import { certifyAiService } from './middlewares/certify-ai-service';
@@ -80,16 +80,25 @@ export const postMessageHandlersFactory: PostMessageHandlersFactory = (crowi) =>
         res.write(`data: ${JSON.stringify(delta)}\n\n`);
         res.write(`data: ${JSON.stringify(delta)}\n\n`);
       };
       };
 
 
-      const sendError = (code: StreamErrorCode, message: string) => {
+      const sendError = (message: string, code?: StreamErrorCode) => {
         res.write(`error: ${JSON.stringify({ code, message })}\n\n`);
         res.write(`error: ${JSON.stringify({ code, message })}\n\n`);
       };
       };
 
 
       stream.on('event', (delta) => {
       stream.on('event', (delta) => {
         if (delta.event === 'thread.run.failed') {
         if (delta.event === 'thread.run.failed') {
-          if (delta.data.last_error?.code === StreamErrorCode.RATE_LIMIT_EXCEEDED) {
-            logger.error(delta.data.last_error.message);
-            sendError(StreamErrorCode.RATE_LIMIT_EXCEEDED, delta.data.last_error.message);
+          const errorMessage = delta.data.last_error?.message;
+          if (errorMessage == null) {
+            return;
           }
           }
+
+          logger.error(errorMessage);
+
+          if (errorMessage === OpenaiStreamErrorMessage.BUDGET_EXCEEDED) {
+            sendError(errorMessage, StreamErrorCode.BUDGET_EXCEEDED);
+            return;
+          }
+
+          sendError(errorMessage);
         }
         }
       });
       });
       stream.on('messageDelta', messageDeltaHandler);
       stream.on('messageDelta', messageDeltaHandler);