kopia lustrzana https://github.com/transitive-bullshit/chatgpt-api
Merge pull request #431 from sighingnow/fix-error-handling
commit
c0c2e716ea
|
@ -219,8 +219,11 @@ export class ChatGPTUnofficialProxyAPI {
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// ignore for now; there seem to be some non-json messages
|
// 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
|
this._fetch
|
||||||
|
|
|
@ -6,10 +6,13 @@ import { streamAsyncIterable } from './stream-async-iterable'
|
||||||
|
|
||||||
export async function fetchSSE(
|
export async function fetchSSE(
|
||||||
url: string,
|
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
|
fetch: types.FetchFn = globalFetch
|
||||||
) {
|
) {
|
||||||
const { onMessage, ...fetchOptions } = options
|
const { onMessage, onError, ...fetchOptions } = options
|
||||||
const res = await fetch(url, fetchOptions)
|
const res = await fetch(url, fetchOptions)
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
let reason: string
|
let reason: string
|
||||||
|
@ -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) {
|
if (!res.body.getReader) {
|
||||||
// Vercel polyfills `fetch` with `node-fetch`, which doesn't conform to
|
// Vercel polyfills `fetch` with `node-fetch`, which doesn't conform to
|
||||||
// web standards, so this is a workaround...
|
// web standards, so this is a workaround...
|
||||||
|
@ -45,13 +73,13 @@ export async function fetchSSE(
|
||||||
body.on('readable', () => {
|
body.on('readable', () => {
|
||||||
let chunk: string | Buffer
|
let chunk: string | Buffer
|
||||||
while (null !== (chunk = body.read())) {
|
while (null !== (chunk = body.read())) {
|
||||||
parser.feed(chunk.toString())
|
feed(chunk.toString())
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
for await (const chunk of streamAsyncIterable(res.body)) {
|
for await (const chunk of streamAsyncIterable(res.body)) {
|
||||||
const str = new TextDecoder().decode(chunk)
|
const str = new TextDecoder().decode(chunk)
|
||||||
parser.feed(str)
|
feed(str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Ładowanie…
Reference in New Issue