From 3ce189b110dbc5e84bb6f9681697711d4064dacb Mon Sep 17 00:00:00 2001 From: "Aman Chadha(IVIXMMI)" <79802170+ac-mmi@users.noreply.github.com> Date: Sun, 9 Feb 2025 16:45:10 +0530 Subject: [PATCH 1/5] Add files via upload --- src/error.ts | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/error.ts b/src/error.ts index f3dc57610..412dc94c3 100644 --- a/src/error.ts +++ b/src/error.ts @@ -23,16 +23,18 @@ export class APIError< readonly request_id: string | null | undefined; constructor(status: TStatus, error: TError, message: string | undefined, headers: THeaders) { - super(`${APIError.makeMessage(status, error, message)}`); + // Always format message when constructing + const formattedMessage = APIError.makeMessage(status, error, message); + super(formattedMessage); // Use formatted message directly this.status = status; this.headers = headers; this.request_id = headers?.['x-request-id']; - this.error = error; + this.error = formattedMessage; - const data = error as Record; - this.code = data?.['code']; - this.param = data?.['param']; - this.type = data?.['type']; + // You can still retain the raw error object for later use, but store the formatted message + this.code = error?.['code']; + this.param = error?.['param']; + this.type = error?.['type']; } private static makeMessage(status: number | undefined, error: any, message: string | undefined) { @@ -40,6 +42,8 @@ export class APIError< error?.message ? typeof error.message === 'string' ? error.message + .replace(/'/g, '"') // Convert single quotes to double quotes + .replace(/\(\s*([^,]+),\s*([^,]+)\s*\)/g, '[$1, $2]') // Convert tuples to arrays (e.g., ('body', 'input') -> ["body", "input"]) : JSON.stringify(error.message) : error ? JSON.stringify(error) : message; @@ -100,6 +104,7 @@ export class APIError< return new InternalServerError(status, error, message, headers); } + // Default to a generic APIError if no specific handling return new APIError(status, error, message, headers); } } From ed4b7bdbbefa535730130b7473b2055bb57243bb Mon Sep 17 00:00:00 2001 From: "Aman Chadha(IVIXMMI)" <79802170+ac-mmi@users.noreply.github.com> Date: Sun, 9 Feb 2025 20:16:23 +0530 Subject: [PATCH 2/5] Add files via upload --- src/streaming.ts | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/streaming.ts b/src/streaming.ts index 6a57a50a0..eeeab2bc1 100644 --- a/src/streaming.ts +++ b/src/streaming.ts @@ -79,8 +79,9 @@ export class Stream implements AsyncIterable { if (e instanceof Error && e.name === 'AbortError') return; throw e; } finally { - // If the user `break`s, abort the ongoing request. - if (!done) controller.abort(); + if (!done && !controller.signal.aborted) { + controller.abort(); // Cleanup only if still active + } } } @@ -126,8 +127,9 @@ export class Stream implements AsyncIterable { if (e instanceof Error && e.name === 'AbortError') return; throw e; } finally { - // If the user `break`s, abort the ongoing request. - if (!done) controller.abort(); + if (!done && response.body) { + response.body.cancel(); + } } } @@ -208,20 +210,22 @@ export async function* _iterSSEMessages( throw new OpenAIError(`Attempted to iterate over a response with no body`); } + const reader = response.body.getReader(); // Explicit reader const sseDecoder = new SSEDecoder(); const lineDecoder = new LineDecoder(); - const iter = ReadableStreamToAsyncIterable(response.body); - for await (const sseChunk of iterSSEChunks(iter)) { - for (const line of lineDecoder.decode(sseChunk)) { - const sse = sseDecoder.decode(line); - if (sse) yield sse; + try { + const iter = ReadableStreamToAsyncIterable(response.body); + for await (const sseChunk of iterSSEChunks(iter)) { + for (const line of lineDecoder.decode(sseChunk)) { + const sse = sseDecoder.decode(line); + if (sse) yield sse; + } } - } - - for (const line of lineDecoder.flush()) { - const sse = sseDecoder.decode(line); - if (sse) yield sse; + } finally { + // Ensure cleanup when stream is done + reader.cancel(); // Explicitly cancel reader + controller.abort(); // Abort request to close socket } } From 260b0c04c049a4c27e054c3efac7c9ea21ac8f8f Mon Sep 17 00:00:00 2001 From: "Aman Chadha(IVIXMMI)" <79802170+ac-mmi@users.noreply.github.com> Date: Sun, 9 Feb 2025 22:59:16 +0530 Subject: [PATCH 3/5] Add files via upload --- src/streaming.ts | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/src/streaming.ts b/src/streaming.ts index eeeab2bc1..6a57a50a0 100644 --- a/src/streaming.ts +++ b/src/streaming.ts @@ -79,9 +79,8 @@ export class Stream implements AsyncIterable { if (e instanceof Error && e.name === 'AbortError') return; throw e; } finally { - if (!done && !controller.signal.aborted) { - controller.abort(); // Cleanup only if still active - } + // If the user `break`s, abort the ongoing request. + if (!done) controller.abort(); } } @@ -127,9 +126,8 @@ export class Stream implements AsyncIterable { if (e instanceof Error && e.name === 'AbortError') return; throw e; } finally { - if (!done && response.body) { - response.body.cancel(); - } + // If the user `break`s, abort the ongoing request. + if (!done) controller.abort(); } } @@ -210,22 +208,20 @@ export async function* _iterSSEMessages( throw new OpenAIError(`Attempted to iterate over a response with no body`); } - const reader = response.body.getReader(); // Explicit reader const sseDecoder = new SSEDecoder(); const lineDecoder = new LineDecoder(); - try { - const iter = ReadableStreamToAsyncIterable(response.body); - for await (const sseChunk of iterSSEChunks(iter)) { - for (const line of lineDecoder.decode(sseChunk)) { - const sse = sseDecoder.decode(line); - if (sse) yield sse; - } + const iter = ReadableStreamToAsyncIterable(response.body); + for await (const sseChunk of iterSSEChunks(iter)) { + for (const line of lineDecoder.decode(sseChunk)) { + const sse = sseDecoder.decode(line); + if (sse) yield sse; } - } finally { - // Ensure cleanup when stream is done - reader.cancel(); // Explicitly cancel reader - controller.abort(); // Abort request to close socket + } + + for (const line of lineDecoder.flush()) { + const sse = sseDecoder.decode(line); + if (sse) yield sse; } } From 1bd2eeb0d35f3ddff34561c5a37076d5c538cb5b Mon Sep 17 00:00:00 2001 From: "Aman Chadha(IVIXMMI)" <79802170+ac-mmi@users.noreply.github.com> Date: Mon, 10 Feb 2025 18:02:46 +0530 Subject: [PATCH 4/5] Add files via upload --- src/error.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/error.ts b/src/error.ts index 412dc94c3..0bbd238e9 100644 --- a/src/error.ts +++ b/src/error.ts @@ -31,10 +31,11 @@ export class APIError< this.request_id = headers?.['x-request-id']; this.error = formattedMessage; - // You can still retain the raw error object for later use, but store the formatted message - this.code = error?.['code']; - this.param = error?.['param']; - this.type = error?.['type']; + const data = error as Record; + this.code = data?.['code']; + this.param = data?.['param']; + this.type = data?.['type']; + } private static makeMessage(status: number | undefined, error: any, message: string | undefined) { From 8a950bc1490928eb32dba889aa15ec0acd22c48c Mon Sep 17 00:00:00 2001 From: "Aman Chadha(IVIXMMI)" <79802170+ac-mmi@users.noreply.github.com> Date: Sat, 22 Feb 2025 00:35:53 +0530 Subject: [PATCH 5/5] Add files via upload --- src/error.ts | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/error.ts b/src/error.ts index 0bbd238e9..2b8a79f59 100644 --- a/src/error.ts +++ b/src/error.ts @@ -35,17 +35,25 @@ export class APIError< this.code = data?.['code']; this.param = data?.['param']; this.type = data?.['type']; + } + + // New helper function to format the error message + private static formatErrorMessage(error: any): string { + if (!error) return ''; + + if (typeof error.message === 'string') { + return error.message + .replace(/'/g, '"') // Convert single quotes to double quotes + .replace(/\(\s*([^()]+?)\s*\)/g, (_, content) => `[${content.split(/\s*,\s*/).join(', ')}]`); + // Convert tuples of any length to arrays + } + return JSON.stringify(error.message ?? error); } private static makeMessage(status: number | undefined, error: any, message: string | undefined) { const msg = - error?.message ? - typeof error.message === 'string' ? - error.message - .replace(/'/g, '"') // Convert single quotes to double quotes - .replace(/\(\s*([^,]+),\s*([^,]+)\s*\)/g, '[$1, $2]') // Convert tuples to arrays (e.g., ('body', 'input') -> ["body", "input"]) - : JSON.stringify(error.message) + error?.message ? APIError.formatErrorMessage(error) : error ? JSON.stringify(error) : message;