diff --git a/packages/@n8n/nodes-langchain/nodes/vendors/OpenAi/actions/router.test.ts b/packages/@n8n/nodes-langchain/nodes/vendors/OpenAi/actions/router.test.ts new file mode 100644 index 0000000000..1331fdd3f9 --- /dev/null +++ b/packages/@n8n/nodes-langchain/nodes/vendors/OpenAi/actions/router.test.ts @@ -0,0 +1,42 @@ +import { mockDeep } from 'jest-mock-extended'; +import type { IExecuteFunctions, INode } from 'n8n-workflow'; +import { NodeApiError } from 'n8n-workflow'; + +import * as audio from './audio'; +import { router } from './router'; + +describe('OpenAI router', () => { + const mockExecuteFunctions = mockDeep(); + const mockAudio = jest.spyOn(audio.transcribe, 'execute'); + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should handle NodeApiError undefined error chaining', async () => { + const errorNode: INode = { + id: 'error-node-id', + name: 'ErrorNode', + type: 'test.error', + typeVersion: 1, + position: [100, 200], + parameters: {}, + }; + const nodeApiError = new NodeApiError( + errorNode, + { message: 'API error occurred', error: { error: { message: 'Rate limit exceeded' } } }, + { itemIndex: 0 }, + ); + + mockExecuteFunctions.getNodeParameter.mockImplementation((parameter) => + parameter === 'resource' ? 'audio' : 'transcribe', + ); + mockExecuteFunctions.getInputData.mockReturnValue([{ json: {} }]); + mockExecuteFunctions.getNode.mockReturnValue(errorNode); + mockExecuteFunctions.continueOnFail.mockReturnValue(false); + + mockAudio.mockRejectedValue(nodeApiError); + + await expect(router.call(mockExecuteFunctions)).rejects.toThrow(NodeApiError); + }); +}); diff --git a/packages/@n8n/nodes-langchain/nodes/vendors/OpenAi/actions/router.ts b/packages/@n8n/nodes-langchain/nodes/vendors/OpenAi/actions/router.ts index 2b64993e2d..876dd88cb1 100644 --- a/packages/@n8n/nodes-langchain/nodes/vendors/OpenAi/actions/router.ts +++ b/packages/@n8n/nodes-langchain/nodes/vendors/OpenAi/actions/router.ts @@ -62,7 +62,7 @@ export async function router(this: IExecuteFunctions) { if (error instanceof NodeApiError) { // If the error is a rate limit error, we want to handle it differently - const errorCode: string | undefined = (error.cause as any).error?.error?.code; + const errorCode: string | undefined = (error.cause as any)?.error?.error?.code; if (errorCode) { const customErrorMessage = getCustomErrorMessage(errorCode); if (customErrorMessage) {