Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
C
Chatgpt Puppeteer
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nanahira
Chatgpt Puppeteer
Commits
90c6e350
Commit
90c6e350
authored
Dec 10, 2022
by
Travis Fischer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: add ChatGPTError with more info on HTTP errors
parent
8cc642e9
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
54 additions
and
12 deletions
+54
-12
src/chatgpt-api.test.ts
src/chatgpt-api.test.ts
+3
-0
src/chatgpt-api.ts
src/chatgpt-api.ts
+36
-10
src/fetch-sse.ts
src/fetch-sse.ts
+8
-2
src/types.ts
src/types.ts
+7
-0
No files found.
src/chatgpt-api.test.ts
View file @
90c6e350
import
test
from
'
ava
'
import
test
from
'
ava
'
import
dotenv
from
'
dotenv-safe
'
import
dotenv
from
'
dotenv-safe
'
import
*
as
types
from
'
./types
'
import
{
ChatGPTAPI
}
from
'
./chatgpt-api
'
import
{
ChatGPTAPI
}
from
'
./chatgpt-api
'
dotenv
.
config
()
dotenv
.
config
()
...
@@ -20,6 +21,7 @@ test('ChatGPTAPI invalid session token', async (t) => {
...
@@ -20,6 +21,7 @@ test('ChatGPTAPI invalid session token', async (t) => {
await
chatgpt
.
ensureAuth
()
await
chatgpt
.
ensureAuth
()
},
},
{
{
instanceOf
:
types
.
ChatGPTError
,
message
:
'
ChatGPT failed to refresh auth token. Error: Unauthorized
'
message
:
'
ChatGPT failed to refresh auth token. Error: Unauthorized
'
}
}
)
)
...
@@ -64,6 +66,7 @@ if (!isCI) {
...
@@ -64,6 +66,7 @@ if (!isCI) {
await
chatgpt
.
ensureAuth
()
await
chatgpt
.
ensureAuth
()
},
},
{
{
instanceOf
:
types
.
ChatGPTError
,
message
:
message
:
'
ChatGPT failed to refresh auth token. Error: session token may have expired
'
'
ChatGPT failed to refresh auth token. Error: session token may have expired
'
}
}
...
...
src/chatgpt-api.ts
View file @
90c6e350
import
ExpiryMap
from
'
expiry-map
'
import
ExpiryMap
from
'
expiry-map
'
import
pTimeout
,
{
TimeoutError
}
from
'
p-timeout
'
import
pTimeout
from
'
p-timeout
'
import
{
v4
as
uuidv4
}
from
'
uuid
'
import
{
v4
as
uuidv4
}
from
'
uuid
'
import
*
as
types
from
'
./types
'
import
*
as
types
from
'
./types
'
...
@@ -68,7 +68,7 @@ export class ChatGPTAPI {
...
@@ -68,7 +68,7 @@ export class ChatGPTAPI {
this
.
_accessTokenCache
=
new
ExpiryMap
<
string
,
string
>
(
accessTokenTTL
)
this
.
_accessTokenCache
=
new
ExpiryMap
<
string
,
string
>
(
accessTokenTTL
)
if
(
!
this
.
_sessionToken
)
{
if
(
!
this
.
_sessionToken
)
{
throw
new
Error
(
'
ChatGPT invalid session token
'
)
throw
new
types
.
ChatGPT
Error
(
'
ChatGPT invalid session token
'
)
}
}
}
}
...
@@ -238,6 +238,7 @@ export class ChatGPTAPI {
...
@@ -238,6 +238,7 @@ export class ChatGPTAPI {
return
cachedAccessToken
return
cachedAccessToken
}
}
let
response
:
Response
try
{
try
{
const
res
=
await
fetch
(
'
https://chat.openai.com/api/auth/session
'
,
{
const
res
=
await
fetch
(
'
https://chat.openai.com/api/auth/session
'
,
{
headers
:
{
headers
:
{
...
@@ -245,8 +246,14 @@ export class ChatGPTAPI {
...
@@ -245,8 +246,14 @@ export class ChatGPTAPI {
'
user-agent
'
:
this
.
_userAgent
'
user-agent
'
:
this
.
_userAgent
}
}
}).
then
((
r
)
=>
{
}).
then
((
r
)
=>
{
response
=
r
if
(
!
r
.
ok
)
{
if
(
!
r
.
ok
)
{
throw
new
Error
(
`
${
r
.
status
}
${
r
.
statusText
}
`
)
const
error
=
new
types
.
ChatGPTError
(
`
${
r
.
status
}
${
r
.
statusText
}
`
)
error
.
response
=
r
error
.
statusCode
=
r
.
status
error
.
statusText
=
r
.
statusText
throw
error
}
}
return
r
.
json
()
as
any
as
types
.
SessionResult
return
r
.
json
()
as
any
as
types
.
SessionResult
...
@@ -255,22 +262,41 @@ export class ChatGPTAPI {
...
@@ -255,22 +262,41 @@ export class ChatGPTAPI {
const
accessToken
=
res
?.
accessToken
const
accessToken
=
res
?.
accessToken
if
(
!
accessToken
)
{
if
(
!
accessToken
)
{
throw
new
Error
(
'
Unauthorized
'
)
const
error
=
new
types
.
ChatGPTError
(
'
Unauthorized
'
)
error
.
response
=
response
error
.
statusCode
=
response
?.
status
error
.
statusText
=
response
?.
statusText
throw
error
}
}
const
error
=
res
?.
error
const
appError
=
res
?.
error
if
(
error
)
{
if
(
appError
)
{
if
(
error
===
'
RefreshAccessTokenError
'
)
{
if
(
appError
===
'
RefreshAccessTokenError
'
)
{
throw
new
Error
(
'
session token may have expired
'
)
const
error
=
new
types
.
ChatGPTError
(
'
session token may have expired
'
)
error
.
response
=
response
error
.
statusCode
=
response
?.
status
error
.
statusText
=
response
?.
statusText
throw
error
}
else
{
}
else
{
throw
new
Error
(
error
)
const
error
=
new
types
.
ChatGPTError
(
appError
)
error
.
response
=
response
error
.
statusCode
=
response
?.
status
error
.
statusText
=
response
?.
statusText
throw
error
}
}
}
}
this
.
_accessTokenCache
.
set
(
KEY_ACCESS_TOKEN
,
accessToken
)
this
.
_accessTokenCache
.
set
(
KEY_ACCESS_TOKEN
,
accessToken
)
return
accessToken
return
accessToken
}
catch
(
err
:
any
)
{
}
catch
(
err
:
any
)
{
throw
new
Error
(
`ChatGPT failed to refresh auth token.
${
err
.
toString
()}
`
)
const
error
=
new
types
.
ChatGPTError
(
`ChatGPT failed to refresh auth token.
${
err
.
toString
()}
`
)
error
.
response
=
response
error
.
statusCode
=
response
?.
status
error
.
statusText
=
response
?.
statusText
error
.
originalError
=
err
throw
error
}
}
}
}
...
...
src/fetch-sse.ts
View file @
90c6e350
import
{
createParser
}
from
'
eventsource-parser
'
import
{
createParser
}
from
'
eventsource-parser
'
import
*
as
types
from
'
./types
'
import
{
fetch
}
from
'
./fetch
'
import
{
fetch
}
from
'
./fetch
'
import
{
streamAsyncIterable
}
from
'
./stream-async-iterable
'
import
{
streamAsyncIterable
}
from
'
./stream-async-iterable
'
...
@@ -10,7 +11,12 @@ export async function fetchSSE(
...
@@ -10,7 +11,12 @@ export async function fetchSSE(
const
{
onMessage
,
...
fetchOptions
}
=
options
const
{
onMessage
,
...
fetchOptions
}
=
options
const
res
=
await
fetch
(
url
,
fetchOptions
)
const
res
=
await
fetch
(
url
,
fetchOptions
)
if
(
!
res
.
ok
)
{
if
(
!
res
.
ok
)
{
throw
new
Error
(
`ChatGPTAPI error
${
res
.
status
||
res
.
statusText
}
`
)
const
msg
=
`ChatGPTAPI error
${
res
.
status
||
res
.
statusText
}
`
const
error
=
new
types
.
ChatGPTError
(
msg
)
error
.
statusCode
=
res
.
status
error
.
statusText
=
res
.
statusText
error
.
response
=
res
throw
error
}
}
const
parser
=
createParser
((
event
)
=>
{
const
parser
=
createParser
((
event
)
=>
{
...
@@ -25,7 +31,7 @@ export async function fetchSSE(
...
@@ -25,7 +31,7 @@ export async function fetchSSE(
const
body
:
NodeJS
.
ReadableStream
=
res
.
body
as
any
const
body
:
NodeJS
.
ReadableStream
=
res
.
body
as
any
if
(
!
body
.
on
||
!
body
.
read
)
{
if
(
!
body
.
on
||
!
body
.
read
)
{
throw
new
Error
(
'
unsupported "fetch" implementation
'
)
throw
new
types
.
ChatGPT
Error
(
'
unsupported "fetch" implementation
'
)
}
}
body
.
on
(
'
readable
'
,
()
=>
{
body
.
on
(
'
readable
'
,
()
=>
{
...
...
src/types.ts
View file @
90c6e350
...
@@ -287,3 +287,10 @@ export type SendConversationMessageOptions = Omit<
...
@@ -287,3 +287,10 @@ export type SendConversationMessageOptions = Omit<
SendMessageOptions
,
SendMessageOptions
,
'
conversationId
'
|
'
parentMessageId
'
'
conversationId
'
|
'
parentMessageId
'
>
>
export
class
ChatGPTError
extends
Error
{
statusCode
?:
number
statusText
?:
string
response
?:
Response
originalError
?:
Error
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment