|
1 | 1 | import type { AiRouter } from '@forestadmin/datasource-toolkit'; |
2 | 2 |
|
3 | | -import { |
4 | | - BadRequestError, |
5 | | - NotFoundError, |
6 | | - UnprocessableError, |
7 | | -} from '@forestadmin/datasource-toolkit'; |
8 | 3 | import { createMockContext } from '@shopify/jest-koa-mocks'; |
9 | 4 |
|
10 | 5 | import AiProxyRoute from '../../../src/routes/ai/ai-proxy'; |
@@ -116,124 +111,20 @@ describe('AiProxyRoute', () => { |
116 | 111 | ); |
117 | 112 | }); |
118 | 113 |
|
119 | | - describe('error handling', () => { |
120 | | - test('should convert error with status 422 to UnprocessableError with original message', async () => { |
121 | | - const route = new AiProxyRoute(services, options, aiRouter); |
122 | | - const error = new Error('AI is not configured') as Error & { status: number }; |
123 | | - error.status = 422; |
124 | | - mockRoute.mockRejectedValueOnce(error); |
125 | | - |
126 | | - const context = createMockContext({ |
127 | | - customProperties: { |
128 | | - params: { route: 'ai-query' }, |
129 | | - query: {}, |
130 | | - }, |
131 | | - requestBody: {}, |
132 | | - }); |
133 | | - |
134 | | - await expect((route as any).handleAiProxy(context)).rejects.toMatchObject({ |
135 | | - name: 'UnprocessableError', |
136 | | - message: 'AI is not configured', |
137 | | - }); |
138 | | - }); |
139 | | - |
140 | | - test('should convert error with status 404 to NotFoundError', async () => { |
141 | | - const route = new AiProxyRoute(services, options, aiRouter); |
142 | | - const error = new Error('Resource not found') as Error & { status: number }; |
143 | | - error.status = 404; |
144 | | - mockRoute.mockRejectedValueOnce(error); |
145 | | - |
146 | | - const context = createMockContext({ |
147 | | - customProperties: { |
148 | | - params: { route: 'ai-query' }, |
149 | | - query: {}, |
150 | | - }, |
151 | | - requestBody: {}, |
152 | | - }); |
153 | | - |
154 | | - await expect((route as any).handleAiProxy(context)).rejects.toThrow(NotFoundError); |
155 | | - }); |
156 | | - |
157 | | - test('should convert error with status 400 to BadRequestError', async () => { |
158 | | - const route = new AiProxyRoute(services, options, aiRouter); |
159 | | - const error = new Error('Invalid input') as Error & { status: number }; |
160 | | - error.status = 400; |
161 | | - mockRoute.mockRejectedValueOnce(error); |
162 | | - |
163 | | - const context = createMockContext({ |
164 | | - customProperties: { |
165 | | - params: { route: 'ai-query' }, |
166 | | - query: {}, |
167 | | - }, |
168 | | - requestBody: {}, |
169 | | - }); |
170 | | - |
171 | | - await expect((route as any).handleAiProxy(context)).rejects.toThrow(BadRequestError); |
172 | | - }); |
173 | | - |
174 | | - test('should convert error with other 4xx/5xx status to UnprocessableError', async () => { |
175 | | - const route = new AiProxyRoute(services, options, aiRouter); |
176 | | - const error = new Error('Server error') as Error & { status: number }; |
177 | | - error.status = 500; |
178 | | - mockRoute.mockRejectedValueOnce(error); |
179 | | - |
180 | | - const context = createMockContext({ |
181 | | - customProperties: { |
182 | | - params: { route: 'ai-query' }, |
183 | | - query: {}, |
184 | | - }, |
185 | | - requestBody: {}, |
186 | | - }); |
187 | | - |
188 | | - await expect((route as any).handleAiProxy(context)).rejects.toThrow(UnprocessableError); |
189 | | - }); |
190 | | - |
191 | | - test('should re-throw unknown errors unchanged', async () => { |
192 | | - const route = new AiProxyRoute(services, options, aiRouter); |
193 | | - const unknownError = new Error('Unknown error'); |
194 | | - mockRoute.mockRejectedValueOnce(unknownError); |
195 | | - |
196 | | - const context = createMockContext({ |
197 | | - customProperties: { |
198 | | - params: { route: 'ai-query' }, |
199 | | - }, |
200 | | - requestBody: {}, |
201 | | - }); |
202 | | - context.query = {}; |
203 | | - |
204 | | - const promise = (route as any).handleAiProxy(context); |
| 114 | + test('should let errors from aiRouter propagate unchanged', async () => { |
| 115 | + const route = new AiProxyRoute(services, options, aiRouter); |
| 116 | + const error = new Error('AI error'); |
| 117 | + mockRoute.mockRejectedValueOnce(error); |
205 | 118 |
|
206 | | - await expect(promise).rejects.toBe(unknownError); |
207 | | - expect(unknownError).not.toBeInstanceOf(UnprocessableError); |
| 119 | + const context = createMockContext({ |
| 120 | + customProperties: { |
| 121 | + params: { route: 'ai-query' }, |
| 122 | + query: {}, |
| 123 | + }, |
| 124 | + requestBody: {}, |
208 | 125 | }); |
209 | 126 |
|
210 | | - test('should log AI proxy errors before converting them', async () => { |
211 | | - const mockLogger = jest.fn(); |
212 | | - const optionsWithLogger = factories.forestAdminHttpDriverOptions.build({ |
213 | | - logger: mockLogger, |
214 | | - }); |
215 | | - const route = new AiProxyRoute(services, optionsWithLogger, aiRouter); |
216 | | - |
217 | | - const error = new Error('Some AI error') as Error & { status: number }; |
218 | | - error.status = 422; |
219 | | - mockRoute.mockRejectedValueOnce(error); |
220 | | - |
221 | | - const context = createMockContext({ |
222 | | - customProperties: { |
223 | | - params: { route: 'ai-query' }, |
224 | | - query: {}, |
225 | | - }, |
226 | | - requestBody: {}, |
227 | | - }); |
228 | | - |
229 | | - await expect((route as any).handleAiProxy(context)).rejects.toThrow(UnprocessableError); |
230 | | - |
231 | | - expect(mockLogger).toHaveBeenCalledWith( |
232 | | - 'Error', |
233 | | - 'AI proxy error: Some AI error', |
234 | | - expect.any(Error), |
235 | | - ); |
236 | | - }); |
| 127 | + await expect((route as any).handleAiProxy(context)).rejects.toBe(error); |
237 | 128 | }); |
238 | 129 | }); |
239 | 130 | }); |
0 commit comments