diff --git a/.changeset/heavy-olives-divide.md b/.changeset/heavy-olives-divide.md new file mode 100644 index 000000000..eebbb2860 --- /dev/null +++ b/.changeset/heavy-olives-divide.md @@ -0,0 +1,5 @@ +--- +'@gitbook/api': patch +--- + +Improve error handling for streamed API operations. diff --git a/bun.lockb b/bun.lockb index 2e8d85976..3251fbff9 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/packages/api/package.json b/packages/api/package.json index b5be46ad3..59860b0b2 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -13,7 +13,7 @@ ], "dependencies": { "event-iterator": "^2.0.0", - "eventsource-parser": "^1.1.1" + "eventsource-parser": "^3.0.0" }, "devDependencies": { "swagger-typescript-api": "^13.0.3", diff --git a/packages/api/templates/http-client.ejs b/packages/api/templates/http-client.ejs index 8d72a187a..1663a4fcd 100644 --- a/packages/api/templates/http-client.ejs +++ b/packages/api/templates/http-client.ejs @@ -2,7 +2,7 @@ const { apiConfig, generateResponses, config } = it; %> import { EventIterator } from 'event-iterator'; -import { createParser, type ParsedEvent, type ReconnectInterval } from 'eventsource-parser'; +import { createParser, type EventSourceMessage } from 'eventsource-parser'; export type QueryParamsType = Record; export type ResponseFormat = keyof Omit; @@ -277,15 +277,23 @@ export class HttpClient { queue.stop(); } - const parser = createParser((event: ParsedEvent | ReconnectInterval) => { - if (event.type === 'event') { - if (event.data === 'done') { + const parser = createParser({ + onEvent: (event: EventSourceMessage) => { + if (event.event === 'done') { stop(); + } else if (event.event === 'error') { + const data = JSON.parse(event.data); + reader.cancel(); + queue.fail(new Error(data.error.message)); } else { const data = JSON.parse(event.data); queue.push(data); } - } + }, + onError: (error) => { + reader.cancel(); + queue.fail(error); + }, }) const decoder = new TextDecoder();