Skip to content

Commit

Permalink
Merge pull request #431 from sighingnow/fix-error-handling
Browse files Browse the repository at this point in the history
  • Loading branch information
transitive-bullshit authored Apr 2, 2023
2 parents 6c309ce + 452a61e commit c0c2e71
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 5 deletions.
5 changes: 4 additions & 1 deletion src/chatgpt-unofficial-proxy-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,11 @@ export class ChatGPTUnofficialProxyAPI {
}
} catch (err) {
// ignore for now; there seem to be some non-json messages
// console.warn('fetchSSE onMessage unexpected error', err)
reject(err)
}
},
onError: (err) => {
reject(err)
}
},
this._fetch
Expand Down
36 changes: 32 additions & 4 deletions src/fetch-sse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ import { streamAsyncIterable } from './stream-async-iterable'

export async function fetchSSE(
url: string,
options: Parameters<typeof fetch>[1] & { onMessage: (data: string) => void },
options: Parameters<typeof fetch>[1] & {
onMessage: (data: string) => void
onError?: (error: any) => void
},
fetch: types.FetchFn = globalFetch
) {
const { onMessage, ...fetchOptions } = options
const { onMessage, onError, ...fetchOptions } = options
const res = await fetch(url, fetchOptions)
if (!res.ok) {
let reason: string
Expand All @@ -33,6 +36,31 @@ export async function fetchSSE(
}
})

// check if the response is an error, if so, throw it
const feed = (chunk: string) => {
let response = null
try {
response = JSON.parse(chunk)
} catch {
/// ignore
}
if (response?.detail) {
if (response.detail.type === 'invalid_request_error') {
const msg = `ChatGPT error ${response.detail.message}: ${response.detail.code} (${response.detail.type})`
const error = new types.ChatGPTError(msg, { cause: response })
error.statusCode = response.detail.code
error.statusText = response.detail.message
if (onError) {
onError(error)
} else {
console.error(error)
}
return // don't feed to event parser
}
}
parser.feed(chunk)
}

if (!res.body.getReader) {
// Vercel polyfills `fetch` with `node-fetch`, which doesn't conform to
// web standards, so this is a workaround...
Expand All @@ -45,13 +73,13 @@ export async function fetchSSE(
body.on('readable', () => {
let chunk: string | Buffer
while (null !== (chunk = body.read())) {
parser.feed(chunk.toString())
feed(chunk.toString())
}
})
} else {
for await (const chunk of streamAsyncIterable(res.body)) {
const str = new TextDecoder().decode(chunk)
parser.feed(str)
feed(str)
}
}
}

0 comments on commit c0c2e71

Please sign in to comment.