11import axios , { AxiosError , AxiosRequestConfig , AxiosResponse , InternalAxiosRequestConfig } from 'axios' ;
22
3+ export function logError ( error : Error , context ?: string ) {
4+ const timestamp = new Date ( ) . toISOString ( ) ;
5+ const contextStr = context ? `[${ context } ] ` : '' ;
6+ const stack = error . stack || '' ;
7+
8+ console . error ( `[${ timestamp } ] ${ contextStr } ${ error . name } : ${ error . message } ` ) ;
9+ console . error ( stack ) ;
10+ }
11+
312export class QuotientAIError extends Error {
413 constructor ( message : string ) {
514 super ( message ) ;
@@ -79,34 +88,66 @@ export class APITimeoutError extends APIConnectionError {
7988
8089export class BadRequestError extends APIStatusError {
8190 status = 400 ;
91+ constructor ( message : string , response : AxiosResponse , body ?: any ) {
92+ super ( message , response , body ) ;
93+ this . name = 'BadRequestError' ;
94+ }
8295}
8396
8497export class AuthenticationError extends APIStatusError {
8598 status = 401 ;
99+ constructor ( message : string , response : AxiosResponse , body ?: any ) {
100+ super ( message , response , body ) ;
101+ this . name = 'AuthenticationError' ;
102+ }
86103}
87104
88105export class PermissionDeniedError extends APIStatusError {
89106 status = 403 ;
107+ constructor ( message : string , response : AxiosResponse , body ?: any ) {
108+ super ( message , response , body ) ;
109+ this . name = 'PermissionDeniedError' ;
110+ }
90111}
91112
92113export class NotFoundError extends APIStatusError {
93114 status = 404 ;
115+ constructor ( message : string , response : AxiosResponse , body ?: any ) {
116+ super ( message , response , body ) ;
117+ this . name = 'NotFoundError' ;
118+ }
94119}
95120
96121export class ConflictError extends APIStatusError {
97122 status = 409 ;
123+ constructor ( message : string , response : AxiosResponse , body ?: any ) {
124+ super ( message , response , body ) ;
125+ this . name = 'ConflictError' ;
126+ }
98127}
99128
100129export class UnprocessableEntityError extends APIStatusError {
101130 status = 422 ;
131+ constructor ( message : string , response : AxiosResponse , body ?: any ) {
132+ super ( message , response , body ) ;
133+ this . name = 'UnprocessableEntityError' ;
134+ }
102135}
103136
104137export class RateLimitError extends APIStatusError {
105138 status = 429 ;
139+ constructor ( message : string , response : AxiosResponse , body ?: any ) {
140+ super ( message , response , body ) ;
141+ this . name = 'RateLimitError' ;
142+ }
106143}
107144
108145export class InternalServerError extends APIStatusError {
109146 status = 500 ;
147+ constructor ( message : string , response : AxiosResponse , body ?: any ) {
148+ super ( message , response , body ) ;
149+ this . name = 'InternalServerError' ;
150+ }
110151}
111152
112153export function parseUnprocessableEntityError ( response : AxiosResponse ) : string {
@@ -123,9 +164,13 @@ export function parseUnprocessableEntityError(response: AxiosResponse): string {
123164 return `missing required fields: ${ missingFields . join ( ', ' ) } ` ;
124165 }
125166 }
126- throw new APIResponseValidationError ( response , body ) ;
167+ const error = new APIResponseValidationError ( response , body ) ;
168+ logError ( error , 'parseUnprocessableEntityError' ) ;
169+ return 'Invalid response format' ;
127170 } catch ( error ) {
128- throw new APIResponseValidationError ( response , null ) ;
171+ const apiError = new APIResponseValidationError ( response , null ) ;
172+ logError ( apiError , 'parseUnprocessableEntityError' ) ;
173+ return 'Invalid response format' ;
129174 }
130175}
131176
@@ -135,9 +180,13 @@ export function parseBadRequestError(response: AxiosResponse): string {
135180 if ( 'detail' in body ) {
136181 return body . detail ;
137182 }
138- throw new APIResponseValidationError ( response , body ) ;
183+ const error = new APIResponseValidationError ( response , body ) ;
184+ logError ( error , 'parseBadRequestError' ) ;
185+ return 'Invalid request format' ;
139186 } catch ( error ) {
140- throw new APIResponseValidationError ( response , null ) ;
187+ const apiError = new APIResponseValidationError ( response , null ) ;
188+ logError ( apiError , 'parseBadRequestError' ) ;
189+ return 'Invalid request format' ;
141190 }
142191}
143192
@@ -153,50 +202,66 @@ export function handleErrors() {
153202 try {
154203 const response = await originalMethod . apply ( this , args ) ;
155204 return response . data ;
156- } catch ( error ) {
157- if ( axios . isAxiosError ( error ) ) {
158- const axiosError = error as AxiosError ;
205+ } catch ( err ) {
206+ if ( axios . isAxiosError ( err ) ) {
207+ const axiosError = err as AxiosError ;
159208
160209 if ( axiosError . response ) {
161210 const { status, data } = axiosError . response ;
162211
163212 switch ( status ) {
164213 case 400 : {
165214 const message = parseBadRequestError ( axiosError . response ) ;
166- throw new BadRequestError ( message , axiosError . response , data ) ;
215+ const error = new BadRequestError ( message , axiosError . response , data ) ;
216+ logError ( error , `${ target . constructor . name } .${ propertyKey } ` ) ;
217+ return null ;
167218 }
168- case 401 :
169- throw new AuthenticationError (
219+ case 401 : {
220+ const error = new AuthenticationError (
170221 'unauthorized: the request requires user authentication. ensure your API key is correct.' ,
171222 axiosError . response ,
172223 data
173224 ) ;
174- case 403 :
175- throw new PermissionDeniedError (
225+ logError ( error , `${ target . constructor . name } .${ propertyKey } ` ) ;
226+ return null ;
227+ }
228+ case 403 : {
229+ const error = new PermissionDeniedError (
176230 'forbidden: the server understood the request, but it refuses to authorize it.' ,
177231 axiosError . response ,
178232 data
179233 ) ;
180- case 404 :
181- throw new NotFoundError (
234+ logError ( error , `${ target . constructor . name } .${ propertyKey } ` ) ;
235+ return null ;
236+ }
237+ case 404 : {
238+ const error = new NotFoundError (
182239 'not found: the server can not find the requested resource.' ,
183240 axiosError . response ,
184241 data
185242 ) ;
243+ logError ( error , `${ target . constructor . name } .${ propertyKey } ` ) ;
244+ return null ;
245+ }
186246 case 422 : {
187247 const unprocessableMessage = parseUnprocessableEntityError ( axiosError . response ) ;
188- throw new UnprocessableEntityError (
248+ const error = new UnprocessableEntityError (
189249 unprocessableMessage ,
190250 axiosError . response ,
191251 data
192252 ) ;
253+ logError ( error , `${ target . constructor . name } .${ propertyKey } ` ) ;
254+ return null ;
193255 }
194- default :
195- throw new APIStatusError (
256+ default : {
257+ const error = new APIStatusError (
196258 `unexpected status code: ${ status } . contact [email protected] for help.` , 197259 axiosError . response ,
198260 data
199261 ) ;
262+ logError ( error , `${ target . constructor . name } .${ propertyKey } ` ) ;
263+ return null ;
264+ }
200265 }
201266 }
202267
@@ -207,15 +272,20 @@ export function handleErrors() {
207272 delay *= 2 ; // Exponential backoff
208273 continue ;
209274 }
210- throw new APITimeoutError ( axiosError . config ) ;
275+ const error = new APITimeoutError ( axiosError . config ) ;
276+ logError ( error , `${ target . constructor . name } .${ propertyKey } ` ) ;
277+ return null ;
211278 }
212279
213- throw new APIConnectionError (
280+ const connectionError = new APIConnectionError (
214281 'connection error. please try again later.' ,
215282 axiosError . config || { url : 'unknown' }
216283 ) ;
284+ logError ( connectionError , `${ target . constructor . name } .${ propertyKey } ` ) ;
285+ return null ;
217286 }
218- throw error ;
287+ logError ( err as Error , `${ target . constructor . name } .${ propertyKey } ` ) ;
288+ return null ;
219289 }
220290 }
221291 } ;
0 commit comments